<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>article Integration Testing for Lakeflow Jobs with Pytest and Databricks Connect in Technical Blog</title>
    <link>https://community.databricks.com/t5/technical-blog/integration-testing-for-lakeflow-jobs-with-pytest-and-databricks/ba-p/141683</link>
    <description>&lt;H1&gt;&lt;SPAN&gt;Introduction&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;&lt;A href="https://www.databricks.com/product/data-engineering" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Databricks Lakeflow&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; enables data teams to design and operate data pipelines at scale, where speed and reliability directly influence the time to market for insights. As pipeline complexity grows, test automation becomes essential to maintaining data quality and ensuring smooth, predictable production workflows. With &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/bundles/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Databricks Asset Bundles&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;, setting up CI/CD and automated testing on Databricks has become significantly simpler, empowering teams to build with confidence and deliver value faster.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Different layers of testing play a role in building reliable data pipelines:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Unit tests validate individual functions or transformations and can run locally (in an IDE or CI agent) using Apache Spark™ and other dependencies in local mode, which is ideal for providing fast feedback during development. While unit tests are lightweight and efficient, they cannot cover certain Databricks-specific capabilities, especially newer features not yet available in open source Spark, Delta, or Unity Catalog.&amp;nbsp; Additionally, they are not intended for testing interactions with external dependencies like Kafka, REST APIs or databases.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Component tests verify how multiple functions or transformations collaborate within a single bounded data pipeline component, ensuring that local logic behaves as intended before integrating with other parts of the data pipeline.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Integration tests then validate complete workflows running on Databricks, confirming that data dependencies, configurations, and platform features behave correctly end-to-end, making them essential for achieving full reliability.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Acceptance and performance tests validate business requirements and scalability in production-like environments.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In this blog, we focus on integration testing, examining two different approaches, and present a blueprint for one of them.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;&lt;SPAN&gt;Integration Testing Approaches&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;&lt;SPAN&gt;Choosing the right approach for integration testing your Lakeflow jobs in Databricks environments is critical for CI/CD maturity, developer productivity, and increasing confidence when deploying changes to a production environment. Two commonly adopted strategies are: Databricks workflow-based integration testing and local integration tests with tools such as &lt;/SPAN&gt;&lt;A href="https://pytest.org/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Pytest&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;. Let’s dive deep into both approaches to see how they work, and their advantages and disadvantages.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Approach 1: Using Databricks Lakeflow Jobs for Integration Testing&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;In this approach, tests are implemented as Databricks notebooks or Python scripts, orchestrated and scheduled via Databricks Lakeflow Jobs. Tests run within the Databricks cloud environment, accessing clusters, data sources, and job code directly. This method requires developers to create and deploy two jobs for each pipeline: a main ETL job and a dedicated integration testing job. The main job handles the ETL tasks, while the integration testing job orchestrates test notebooks to set up environments, execute main jobs, validate results, and clean up resources.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The approach consists of the following phases, each executed as a separate task within the integration test job:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Setup task: Create isolated test resources (catalogs, schemas, tables) and populate them with test data&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Trigger task: Run the actual Lakeflow job against the prepared test environment&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Validation task: Assert expected outcomes and validate data quality&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Teardown task: Clean up test resources to prevent catalog/workspace clutter&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Typically, the integration testing job is deployed and run only in specific environments (e.g. test, acceptance) through a CI/CD process. To ensure isolation and environment-specific functionality, the main ETL job must be parameterized, allowing all environment-dependent values (catalogs, schemas, paths) to be configurable via notebook parameters. The CI agent is responsible for deploying, executing, and validating the integration test results, thereby determining if the build is successful or a failure.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;However, this approach presents several drawbacks, primarily due to the necessity of creating and deploying a secondary job for testing alongside the main job. These include:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Defining setup and teardown logic&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Defining the secondary integration testing job with the correct tasks and order&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Deploying both jobs to the appropriate environment (either locally or through a CI agent)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Polling and parsing job results&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Additionally, the approach slows down the feedback loop during both test and job development. Running tests requires deploying both jobs with the right parameters to the right environment, running them, waiting for results, and interpreting those results. This context switching breaks the developer flow.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Approach 2: Using Pytest for Integration Testing&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;In this approach, tests are written locally using Pytest and developed in your preferred IDE with full debugging capabilities. Tests leverage &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/databricks-connect/python/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Databricks Connect&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; to establish a remote execution context on Databricks clusters while orchestrating everything from your local machine or a CI agent. Integration tests are written using Pytest, leveraging its capability for setting up and tearing down resources through fixtures, triggering the job to be tested, and validating the results afterward through Pytest assertions.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The typical workflow is:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Test Setup: Pytest fixtures use Databricks Connect to create test-specific resources (catalogs, schemas, tables) using the remote cluster, establishing an isolated test environment.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Job Execution: The Lakeflow job is triggered to run on Databricks, operating against the test data and environment.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Result Validation: After job completion, Pytest assertions query results through Databricks Connect, validating outputs, data quality, and business logic.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Teardown: Test fixtures clean up resources, removing test-created catalogs, schemas, and tables to maintain workspace hygiene and prevent test interference.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Similar to the first approach, the main job under test must be parameterized for all environments with test-specific values configured during test execution. This ensures test isolation, as resources are created specifically for each test run. Developers can execute the test either locally or via a CI agent without deploying additional jobs to Databricks, enabling them to assert job execution results remotely. Pytest also offers test reporting, which helps in validating and quickly identifying successful and failing tests.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;This approach provides the benefits of:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Rapid Development and Iteration: Tests are developed, executed, and debugged locally without additional deployments or workflow scheduling.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Tight Feedback Loops: Developers see results in the same IDE without the need to switch between different tools and UI during active development.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Complete Pytest Ecosystem Access: Access to fixtures for complex setup/teardown logic, parametrization for testing multiple scenarios, powerful assertions, and hundreds of plugins for specialized testing needs.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Remote Execution: Still executes within the Databricks environment through remote execution using Databricks Connect.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;&amp;nbsp;&lt;/H1&gt;
&lt;H1&gt;&lt;SPAN&gt;Approach 2 Deep Dive&lt;/SPAN&gt;&lt;/H1&gt;
&lt;H2&gt;&lt;SPAN&gt;Blueprint Overview&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;At its core, this blueprint defines a pytest-driven framework to run integration tests on each Lakeflow job (with multiple tasks). Every test case follows a standardized structure focused on reproducibility, isolation, and full verification of pipeline outputs.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Pytest Template Structure&lt;/SPAN&gt;&lt;/H2&gt;
&lt;H3&gt;&lt;SPAN&gt;Setup Phase&lt;/SPAN&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Establishes a predefined, isolated clean state by creating new ephemeral Unity Catalog schemas and volumes required for each test run, ensuring every run is consistent and independent of prior (and parallel) executions. Note that Unity Catalog schema and volume creation privileges are required to execute integration tests.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;SPAN&gt;Trigger Phase&lt;/SPAN&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Invokes the deployed Databricks workflow via the Workspace client, initiated from within a pytest fixture.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Supports parameterization to test multiple pipeline configurations, allowing each test to run in parallel and isolation on its own Unity Catalog schema.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;The trigger emulates a production job, validating orchestration logic and Databricks-specific dependencies that local Spark tests cannot achieve.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;SPAN&gt;Assertion and Cleanup Phase&lt;/SPAN&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;After workflow completion, assertions validate the resulting state in Unity Catalog tables.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Typical validations include:&lt;/SPAN&gt;&lt;/LI&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="2"&gt;&lt;SPAN&gt;Record counts in Delta or Iceberg tables.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="2"&gt;&lt;SPAN&gt;Comparing records to stored snapshots.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Cleanup logic tears down or deletes the ephemeral resources, such as tables, checkpoints, and volumes.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Each test execution provides consistent validation against real Databricks runtime behavior, from workflow orchestration to data persistence, while preserving the speed and productivity of local workflows.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Orchestrating Tests with databricks-labs-pytester&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The &lt;/SPAN&gt;&lt;A href="https://github.com/databrickslabs/pytester" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;databricks-labs-pytester&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; package is a valuable utility for orchestrating integration tests with Databricks, enhancing pytest by providing native Databricks capabilities for resource management, Spark session handling and test isolation.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN&gt;Key benefits&lt;/SPAN&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Prebuilt fixtures handle environment setup, such as the creation of ephemeral Unity Catalog schemas and volumes required for each test.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Workspace integration exposes convenient APIs (through the &lt;/SPAN&gt;&lt;SPAN&gt;ws&lt;/SPAN&gt;&lt;SPAN&gt; fixture) to trigger and monitor Databricks workflows.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Lifecycle consistency guarantees clean setup and teardown execution even when tests fail.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Here’s an example integration test showing these concepts in action:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;@pytest.mark.integration_test
def test_job(spark, make_schema, ws, job_id):
    catalog_name = "main"

    # Ephemeral schema creation
    schema_name = make_schema(catalog_name=catalog_name).name

    # Trigger a Databricks Workflow run
    run_wait = ws.jobs.run_now(
        job_id=job_id,
        python_params=[catalog_name, schema_name]
    )

    # Wait for run completion and validate success
    run_result = run_wait.result()
    result_status = run_result.state.result_state
    assert result_status == RunResultState.SUCCESS

    # Validate result data written to Unity Catalog table
    df = spark.read.table(f"{catalog_name}.{schema_name}.my_table")
    assert df.count() &amp;gt; 0

@pytest.fixture
def job_id(ws, request):
  job_name = request.config.getoption("--job-name")
  job_id = next((job.job_id for job in ws.jobs.list() if job.settings.name == job_name), None)
  if job_id is None:
      raise ValueError(f"Job '{job_name}' not found.")

  return job_id&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;In this test:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;make_schema&lt;/SPAN&gt; &lt;SPAN&gt;creates an ephemeral Unity Catalog schema required for this specific test.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;ws&lt;/SPAN&gt; &lt;SPAN&gt;gives a handle to the Databricks Workspace client, allowing direct workflow triggering via &lt;/SPAN&gt;&lt;SPAN&gt;run_now&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Post-execution, data is validated through the &lt;/SPAN&gt;&lt;SPAN&gt;spark&lt;/SPAN&gt; &lt;SPAN&gt;fixture powered by Databricks Connect, demonstrating full end-to-end validation from orchestration to data verification.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;This minimal example demonstrates both Pytester’s fixture-driven simplicity and its tight integration with Lakeflow jobs, enabling well-readable, fully automated tests optimized for CI/CD.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Leveraging DB Connect&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;While Pytester manages Databricks resource orchestration and improves the test code structure, Databricks Connect powers the actual Spark execution on any Databricks compute, including serverless compute. Databricks Serverless provides instant, on-demand compute, which is critical for fast test completion within both inner and outer development loops.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Through Databricks Connect, tests:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Operate natively with Unity Catalog assets on Databricks.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Execute Spark transformations and queries for setup or assertion phases remotely on the Databricks runtime.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Maintain parity with production configurations without requiring local Spark clusters.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Managing Python Environments with the &lt;/SPAN&gt;&lt;A href="https://docs.astral.sh/uv/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;uv&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; package manager&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Unit and integration tests depend on different Spark and Databricks runtime contexts. The UV package manager makes it easy to enforce dependency isolation across these layers through&lt;/SPAN&gt; &lt;SPAN&gt;pyproject.toml&lt;/SPAN&gt; &lt;SPAN&gt;dependency groups.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Example configuration from&lt;/SPAN&gt;&lt;SPAN&gt; pyproject.toml&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;[dependency-groups]
dev = [
    "pytest&amp;gt;=8.3.4",
    "databricks-labs-pytester"
]
unit-tests = [
    # These dependencies will break integration tests relying on databricks-connect
    "pyspark&amp;gt;=4.0.0,&amp;lt;5.0.0"
]
integration-tests = [
    "databricks-connect==17.1.0"
]&lt;/LI-CODE&gt;
&lt;H3&gt;&lt;SPAN&gt;Usage patterns&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;Run integration tests:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;#bash
uv sync --only-group integration-tests
uv run python -m pytest -rsx -m integration_test --job-name="&amp;lt;job-name-to-test&amp;gt;"&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;Run unit tests:&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;#bash
uv sync --only-group unit-tests
uv run python -m pytest -m unit_test&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;With isolated dependency groups, data teams can confidently test across multiple layers while maintaining a single, consistent repository. Shared dependencies under the&lt;/SPAN&gt; &lt;SPAN&gt;dev&lt;/SPAN&gt; &lt;SPAN&gt;group reduce duplication and ensure identical setups both locally and within CI/CD executions.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H1&gt;&amp;nbsp;&lt;/H1&gt;
&lt;H1&gt;&lt;SPAN&gt;Demo&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;&lt;SPAN&gt;The following section showcases how this setup will run in an actual Databricks environment.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;The full demo code is available in the &lt;/SPAN&gt;&lt;A href="https://github.com/databricks-solutions/databricks-blogposts/tree/main/2025-12-integration-tests-blueprint-demo" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Databricks Blogposts&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; GitHub repository.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Setting up the environment&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Prerequisite:&amp;nbsp; Install and setup the following dependencies&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/cli/install" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Install and set up Databricks CLI locally&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://docs.astral.sh/uv/guides/install-python/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Install Python uv&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/cli/authentication" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Authenticate the Databricks CLI to your dev workspace&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Install required Python dependencies using &lt;/SPAN&gt;&lt;SPAN&gt;uv&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;LI-CODE lang="markup"&gt;#bash
uv sync --only-group integration-tests&lt;/LI-CODE&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Set up the following environment variables for Pytester&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;LI-CODE lang="markup"&gt;export DATABRICKS_HOST=&amp;lt;your-dev-workspace-url&amp;gt;
export DATABRICKS_CLUSTER_ID=&amp;lt;cluster-id&amp;gt; # Used to run Spark code on Databricks
export DATABRICKS_WAREHOUSE_ID=&amp;lt;warehouse-id&amp;gt; # Used by pytester fixtures to run SQL queries 

# Optionally if you want to use serverless instead of classic compute, replace DATABRICKS_CLUSTER_ID with this
export DATABRICKS_SERVERLESS_COMPUTE_ID=auto&lt;/LI-CODE&gt;
&lt;H2&gt;&lt;SPAN&gt;Bundling and deploying the job&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Set up a Databricks Assets Bundle for the main job which will make it easy to define and deploy the job to different target environments.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Example job definition:&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;# ./resources/workflow_test_automation_blueprint.job.yml
resources:
  jobs:
    workflow_test_automation_blueprint_job:
      name: workflow_test_automation_blueprint_job
      tasks:
        - task_key: calculate_avg_trip_distance
          python_wheel_task:
            entry_point: main
            package_name: ps_test_blueprint
            parameters: ["main","default"]
          environment_key: default
      environments:
        - environment_key: default
          spec:
            environment_version: '3'
            dependencies:
              - ../dist/*.whl&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;Example &lt;/SPAN&gt;&lt;SPAN&gt;databricks.yml&lt;/SPAN&gt;&lt;SPAN&gt; file&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;bundle:
  name: workflow_test_automation_blueprint

include:
  - resources/*.yml

artifacts:
  default:
    type: whl
    build: uv build --wheel --package ps_test_blueprint
    path: .

targets:
  dev:
    mode: development
    default: true&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;Once the YAML files are defined and configured properly, deploy the main job to be tested toward a Databricks environment where you want to test the job. In this example, it will be deployed to a dev environment.&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;databricks bundle deploy -t dev&lt;/LI-CODE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Taras_Chaikovsk_0-1765466452035.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/22221iB040759EF4FC0B09/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Taras_Chaikovsk_0-1765466452035.png" alt="Taras_Chaikovsk_0-1765466452035.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Running the integration tests&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Next, execute the integration tests, which will set up the environment through fixtures, trigger the main job that was deployed in the previous step, and validate the results of the job run. This can be run multiple times for the same job deployed in the previous step.&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="markup"&gt;uv run python -m pytest -rsx -m integration_test --job-name="workflow_test_automation_blueprint_job"&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN&gt;Once the test runs, a new test-specific schema is created to store the output tables and is passed to the job as a parameter. The main job started running as well.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Taras_Chaikovsk_1-1765466452036.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/22222i921C14EA060B9D1F/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Taras_Chaikovsk_1-1765466452036.png" alt="Taras_Chaikovsk_1-1765466452036.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The schema &lt;/SPAN&gt;&lt;SPAN&gt;dummy_*&lt;/SPAN&gt;&lt;SPAN&gt; is created by Pytester fixture specifically for the tests.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Taras_Chaikovsk_2-1765466452037.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/22220i1E855DD3106CF84F/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Taras_Chaikovsk_2-1765466452037.png" alt="Taras_Chaikovsk_2-1765466452037.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Results and cleanup&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The main job ran successfully and the results are returned to the test to be validated. Marking the tests a success and producing the pytest report&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Taras_Chaikovsk_3-1765466452037.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/22223i6D01D11647F62290/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Taras_Chaikovsk_3-1765466452037.png" alt="Taras_Chaikovsk_3-1765466452037.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The schema and any resources created specifically for the test are automatically deleted after the test run.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Taras_Chaikovsk_4-1765466452038.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/22224i5D8C75AFF788AA29/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Taras_Chaikovsk_4-1765466452038.png" alt="Taras_Chaikovsk_4-1765466452038.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;&lt;SPAN&gt;Conclusion&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;&lt;SPAN&gt;In this blog, we explored two approaches for integration testing of Lakeflow Jobs and presented a practical blueprint for Approach 2 using Pytest and Databricks Connect. By combining Pytest’s&amp;nbsp; framework, including advanced fixture management through databricks-pytester, with Databricks Connect’s remote job execution, data teams gain faster feedback cycles, higher developer productivity, and more reliable data pipelines. This streamlined workflow empowers teams to test the entire lifecycle, from orchestration and external dependencies to data persistence, directly within their IDE or CI environment.&lt;/SPAN&gt;&lt;/P&gt;</description>
    <pubDate>Wed, 17 Dec 2025 14:02:31 GMT</pubDate>
    <dc:creator>Taras_Chaikovsk</dc:creator>
    <dc:date>2025-12-17T14:02:31Z</dc:date>
    <item>
      <title>Integration Testing for Lakeflow Jobs with Pytest and Databricks Connect</title>
      <link>https://community.databricks.com/t5/technical-blog/integration-testing-for-lakeflow-jobs-with-pytest-and-databricks/ba-p/141683</link>
      <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Screenshot 2025-12-11 at 16.18.44.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/22219iE979563CD7870565/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Screenshot 2025-12-11 at 16.18.44.png" alt="Screenshot 2025-12-11 at 16.18.44.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 17 Dec 2025 14:02:31 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/integration-testing-for-lakeflow-jobs-with-pytest-and-databricks/ba-p/141683</guid>
      <dc:creator>Taras_Chaikovsk</dc:creator>
      <dc:date>2025-12-17T14:02:31Z</dc:date>
    </item>
    <item>
      <title>Re: Integration Testing for Lakeflow Jobs with Pytest and Databricks Connect</title>
      <link>https://community.databricks.com/t5/technical-blog/integration-testing-for-lakeflow-jobs-with-pytest-and-databricks/bc-p/149712#M944</link>
      <description>&lt;P&gt;Thanks for this very helpful and informative blog post.&lt;/P&gt;&lt;P&gt;I’d appreciate more recommendations on integration testing for jobs that orchestrate Lakeflow pipelines with streaming tables as targets. Any guidance or patterns for testing streaming pipeline jobs safely and reproducibly—such as isolating streaming state and schemas for each test—would be extremely useful.&lt;/P&gt;&lt;P&gt;Thanks again for the excellent content!&lt;/P&gt;</description>
      <pubDate>Tue, 03 Mar 2026 15:32:13 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/integration-testing-for-lakeflow-jobs-with-pytest-and-databricks/bc-p/149712#M944</guid>
      <dc:creator>de_ig</dc:creator>
      <dc:date>2026-03-03T15:32:13Z</dc:date>
    </item>
    <item>
      <title>Re: Integration Testing for Lakeflow Jobs with Pytest and Databricks Connect</title>
      <link>https://community.databricks.com/t5/technical-blog/integration-testing-for-lakeflow-jobs-with-pytest-and-databricks/bc-p/151177#M950</link>
      <description>&lt;P&gt;Great question! We've heard this from several folks. We're planning a Part 2 of the blog focused specifically on integration testing SDP pipelines.&lt;/P&gt;
&lt;P&gt;A quick preview of the key insights we'll cover:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Fresh pipeline per test is the way to go. Reusing a deployed pipeline across tests breaks because the pipeline's internal metadata retains references to previously dropped ephemeral schemas. Instead, read the deployed pipeline's spec and create a new isolated pipeline instance (via ws.pipelines.create() from the Databricks SDK for Python) targeting each test's ephemeral schema.&lt;/LI&gt;
&lt;LI&gt;Watch out: the SDK's wait_get_pipeline_idle() returns on failure too - always verify the latest update status is COMPLETED before asserting on table contents.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Stay tuned!&lt;/P&gt;</description>
      <pubDate>Wed, 18 Mar 2026 08:56:44 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/integration-testing-for-lakeflow-jobs-with-pytest-and-databricks/bc-p/151177#M950</guid>
      <dc:creator>Taras_Chaikovsk</dc:creator>
      <dc:date>2026-03-18T08:56:44Z</dc:date>
    </item>
    <item>
      <title>Re: Integration Testing for Lakeflow Jobs with Pytest and Databricks Connect</title>
      <link>https://community.databricks.com/t5/technical-blog/integration-testing-for-lakeflow-jobs-with-pytest-and-databricks/bc-p/156129#M1041</link>
      <description>&lt;P&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/35260"&gt;@Taras_Chaikovsk&lt;/a&gt;&amp;nbsp;is the part 2 already out?&lt;/P&gt;</description>
      <pubDate>Tue, 05 May 2026 05:57:16 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/integration-testing-for-lakeflow-jobs-with-pytest-and-databricks/bc-p/156129#M1041</guid>
      <dc:creator>yit337</dc:creator>
      <dc:date>2026-05-05T05:57:16Z</dc:date>
    </item>
  </channel>
</rss>

