Skip to main content

pytest-airflow-in-a-box logo

pytest-airflow-in-a-box

CI coverage PyPI Python versions License Docs Airflow

Your Dag files import. Your task callables pass. Production still breaks.

Did you verify the DAG?

Import and callable tests do not exercise trigger rules, branch skips, rendered templates, connection resolution, or operator serialization. pytest-airflow-in-a-box tests those seams in pytest, before deployment -- no scheduler, webserver, or live Airflow environment required.

For teams that own Airflow behavior: Dags in a repository, custom operators, hooks, sensors, connection types, live REST API integrations, or an Airflow 2-to-3 migration. If your repo is 100% stock operators, dag.test() plus a DagBag import test is enough; the full list is on the documentation site.

Already have a DagBag import test and a pile of task.function(...) calls? Here is exactly where they stop, and why not dag.test(), DebugExecutor, or your own conftest.py.

Quickstart

def test_my_dag(dag_bag, run_dag):
    dag = dag_bag.dags["my_dag_id"]

    result = run_dag(dag)

    assert result.success
    assert result.order == ["extract", "load"]
pytest --dag-folder=dags

run_dag proves your real file, under its real dag_id, actually finishes in the states you expect. dag_bag parses the folder once per worker process, and result.order records execution order rather than graph topology. In-test Dags (dag_maker), single operators without a database (run_task), and matchers are in the Quickstart.

Installation

uv add --dev "pytest-airflow-in-a-box[airflow3]"

The plugin does not depend on Airflow directly: the Airflow 2.x monolith and the 3.x core both install under the name apache-airflow, so a hard plugin pin would corrupt whichever family you did not choose. The airflow3 extra pins apache-airflow>=3.1,<4, matching the dependency restriction in pyproject.toml. Projects that already pin Airflow themselves -- for example through Airflow's published constraints files -- install the plugin bare. Every extra and common combination is listed under Dependencies and extras.

GitHub Action

nredd/pytest-airflow-in-a-box/action@v0 provisions a constraints-pinned Airflow environment; your workflow still runs pytest.

name: Airflow tests

on: [pull_request]

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: nredd/pytest-airflow-in-a-box/action@v0
        id: airflow-env
        with:
          airflow-version: "3.3.1"
          python-version: "3.13"
      - run: ${{ steps.airflow-env.outputs.python-path }} -m pytest

The action does not run tests, cache packages, upload artifacts, or start Docker. See GitHub Actions and reports for every input and output, report uploads, version matrices, and pinning.

Requirements

  • CPython 3.10 through 3.14, pytest 8 or newer
  • Apache Airflow 3.1 or newer, below 4; or a certified Airflow 2 release from 2.7 through 2.11
  • Linux or macOS. Airflow has no native Windows support -- use WSL2 or the devcontainer

Which Airflow and Python combinations are actually exercised in CI, and what the 2.x tier does and does not cover, are stated once in Compatibility and certification. After installing, pytest --airflow-doctor tells you whether your own pin works.

What ships

Typed fixtures, grouped by the job:

Job Reach for
Run one operator with no database run_task, render_task, task_context
Run a real DagRun and assert on it dag_maker, run_dag, dag_bag
Give the run its environment airflow_home, airflow_configure, airflow_variables, airflow_connections
Register a custom component for one test airflow_components
Assert on what a task logged cap_structlog
Check every Dag at once dag_corpus
Talk to a live Airflow API api_client, api_base_url

Every fixture, its return type, and its scope: Fixtures. Markers are listed in Markers.

Also in the box: corpus smoke checks (--airflow-smoke), a disposable metadata database, an isolated AIRFLOW_HOME, report artifacts that survive -n auto, a GitHub Action, and an Airflow 2-to-3 migration toolkit fronted by the airflow-migration-diff console script.

Documentation

The documentation site follows the reader, one deep link per stage:

Contributing, the local gate, and running CI with act: CONTRIBUTING.md and Developing this plugin.

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.13.1.tar.gz (359.0 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.13.1-py3-none-any.whl (409.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pytest_airflow_in_a_box-0.13.1.tar.gz
  • Upload date:
  • Size: 359.0 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.13.1.tar.gz
Algorithm Hash digest
SHA256 7d80e1f64d040e4f8d902e356c845f57f80195652cc4ec3019ac502595e37d86
MD5 604a4f986d119b4642ad17c5d5cae23e
BLAKE2b-256 955406ec43a5b28055be76e211d32d90944a020bae431ec2efa5f3e355348967

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_airflow_in_a_box-0.13.1.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.13.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_airflow_in_a_box-0.13.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7cae7b019dac199b3f4396ab984935a1d4a4438d02fca0b36b3eae5b9440987a
MD5 fb11273d73b0ebc9de6157d1dfdff7f7
BLAKE2b-256 2355e3519455b435bdd0c77c0bbade6cbc86bd0a1d86fbf47d0ef1ff31ab1168

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_airflow_in_a_box-0.13.1-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

This release

0.13.1 This release

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

0.4.0

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