Skip to main content

pytest-airflow-in-a-box

CI coverage PyPI Python versions License

pytest-airflow-in-a-box is a pytest plugin for testing Apache Airflow DAGs without a live Airflow deployment. It targets Airflow 3 and provides the package and plugin foundation for a small, typed testing surface.

The package auto-registers with pytest, creates an isolated metadata database, and provides typed fixtures for persisted Dags, DagRuns, task instances, sessions, and Dag bags.

Contents

Quickstart

uv add --dev pytest-airflow-in-a-box
pip install pytest-airflow-in-a-box
from airflow.sdk import task


def test_dag(dag_maker):
    with dag_maker():

        @task
        def produce():
            return 21

        @task
        def consume(value):
            return value * 2

        consume(produce())

    result = dag_maker.run()

    assert result.success
    assert result.xcoms == {"produce": 21, "consume": 42}
    assert result.order == ["produce", "consume"]
pytest

dag_maker.run() executes every task in dependency order and returns an inert DagRunResult snapshot: states, xcoms, errors, order, and per-task access via result["task_id"]. Single tasks run with dag_maker.run_ti("produce"), and pytest_airflow_in_a_box.matchers supports one-expression bulk assertions like assert result == {"produce": succeeded(21), "consume": succeeded(42)}.

The pytest11 entry point registers the plugin automatically -- no pytest_plugins declaration needed. See the documentation site for the full dag_maker/run/run_ti surface, sessions, DB-free task execution, deferrable operators, the REST API fixture, and bundled smoke checks.

Why not...

  • dag.test() -- Airflow's own built-in helper runs one Dag end to end, but it is not a pytest plugin: no fixtures, no isolated metadata database, no xdist parallelism, no REST API testing
  • upstream tests_common -- the harness Airflow's own core test suite runs on; it targets testing Airflow itself, not published as a package for testing DAG-author code
  • Flowminder pytest-airflow -- an inverse concept (runs pytest suites under Airflow, rather than testing DAGs under pytest) and unmaintained
  • airflow-pytest-plugin -- generates JUnit-XML dashboards from DAG runs; not aimed at isolated, fixture-driven unit testing

Requirements

  • CPython 3.10 through 3.14
  • pytest 8 or newer
  • Apache Airflow 3.1 or newer, below 4
  • Linux or macOS for Airflow-backed tests

Apache Airflow does not support native Windows installations. Windows development should use WSL2 or the included devcontainer; platform-independent package checks alone do not imply full Windows Airflow support.

The released compatibility matrix is exercised against Airflow 3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.5, 3.1.6, 3.1.7, 3.1.8, 3.2.0, 3.2.1, 3.2.2, and 3.3.0 across CPython 3.10 through 3.14 using Airflow's published constraints files.

Installation

uv add --dev pytest-airflow-in-a-box
pip install pytest-airflow-in-a-box

The pytest11 entry point loads the plugin automatically. Consumer projects do not need to add a pytest_plugins declaration.

The bundled pytest plugins are intentional runtime dependencies. pytest-xdist is part of the supported execution model: controller bootstrap state and worker-scoped artifacts are coordinated for parallel runs. pytest-timeout backs up Airflow's per-file Dag parse watchdog with a corpus-scaled deadline on every bundled smoke item, so whichever worker produces the shared corpus cannot wedge the test session outside the per-file parser boundary.

The plugin is inert on runs without Airflow-facing tests: session startup only prepares a disposable run directory and AIRFLOW__* environment variables. Airflow itself is imported and the metadata database migrated lazily, on the first test that carries a db_test/api_test marker or uses a database-backed plugin fixture. A pytest -k unrelated run in a shared venv never pays the Airflow import or migration cost. Tests that touch the metadata database directly (their own create_session calls, for example) without a plugin fixture must carry db_test to trigger initialization.

To disable the plugin entirely for a run:

pytest -p no:pytest_airflow_in_a_box

Documentation

Task execution, deferrable operators, DB-free execution, Variable/Connection seeding, structlog capture, Dag collection, configuration overrides, smoke tests, database backends and cleanup, the live REST API, markers, and diagnostics are all covered on the documentation site.

Development

uv sync
uv run prek install
make all

Run the GitHub Actions workflow locally on Linux with act:

act pull_request

act cannot reproduce native macOS or Windows behavior. See CONTRIBUTING.md for the full contribution workflow and the issue tracker for open work.

License

Apache License 2.0. See LICENSE, NOTICE, and PROVENANCE.md.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_airflow_in_a_box-0.4.0.tar.gz (105.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_airflow_in_a_box-0.4.0-py3-none-any.whl (130.3 kB view details)

Uploaded Python 3

File details

Details for the file pytest_airflow_in_a_box-0.4.0.tar.gz.

File metadata

  • Download URL: pytest_airflow_in_a_box-0.4.0.tar.gz
  • Upload date:
  • Size: 105.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pytest_airflow_in_a_box-0.4.0.tar.gz
Algorithm Hash digest
SHA256 eb9d8f43b98a43b3c2ff40bdc02a0b8e0347d5eb66fb72d80c31fa9f87f8b5cd
MD5 1d58be0bec64c1338c915778f6af69c3
BLAKE2b-256 49fd156cba8bc53fe3d04244c4aad16e2ac77e5456dd49944ff549ff429b7814

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_airflow_in_a_box-0.4.0.tar.gz:

Publisher: release.yml on nredd/pytest-airflow-in-a-box

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pytest_airflow_in_a_box-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_airflow_in_a_box-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8f787f28783c6da150bee5bc212a3e5834af1fee6ea2906c2af5261476a55b90
MD5 9a2714c155033d32bffe468f9090f454
BLAKE2b-256 d42c4142898cd8c9baedb279c7e6d1722cdb3cb08f3b7bbf1ae2498c946fdfb4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_airflow_in_a_box-0.4.0-py3-none-any.whl:

Publisher: release.yml on nredd/pytest-airflow-in-a-box

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.13.1

2 files

0.13.0

2 files

0.12.0

2 files

0.11.1

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

This release

0.4.0 This release

2 files

0.3.0

2 files

0.2.0

2 files

0.1.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page