pytest-airflow-in-a-box
Your Dag files import cleanly and your callables pass. This proves the seams between them
work -- in your own CI, with no scheduler, no webserver, and no ~/airflow.
For a team owning a dags/ repo on Airflow 3 that writes its own operators, hooks, sensors,
and connection types. Not for testing Airflow's own machinery, which Airflow already tests.
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 settles the way you think.
result.order is the executed order, not graph topology.
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 the airflow package, so a hard plugin pin would corrupt whichever family you did not
choose. The airflow3 extra pins apache-airflow>=3.1,<4. Projects that already pin Airflow
themselves -- for example through Airflow's published constraints files -- install the plugin
bare. Full detail:
Installing the plugin.
Requirements
- CPython 3.10 through 3.14, pytest 8 or newer
- Apache Airflow 3.1+ below 4, or 2.7+ below 3 on the certified 2.x tier
- 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
Supported Airflow and Python versions.
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 |
| 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:
- Why test your Dag code -- the failures that need a DagRun to exist
- Deciding which failures are yours -- what earns a test
- The fidelity ladder -- which rung to stand on, and what each one costs
- Smoke checks over every Dag -- properties of the whole corpus
- Migrating from Airflow 2 to 3 -- arrive migrating, leave with a suite
- Under the hood -- what
_compat/absorbs, and why - Vision -- what this is for, and what it is not
Contributing, the local gate, and running CI with act:
CONTRIBUTING.md and
Working on the plugin itself.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_airflow_in_a_box-0.12.0.tar.gz.
File metadata
- Download URL: pytest_airflow_in_a_box-0.12.0.tar.gz
- Upload date:
- Size: 353.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
190e64db34c900a819d39424547ced3fffb6851a735b4aef7a4cb12dc838f298
|
|
| MD5 |
c7b47eefbb63ba312ba1bcdbbe58b992
|
|
| BLAKE2b-256 |
da57d4e8c4de8bde5b400842ebe253de24d6893ca5906bc1cddc09c43a34c3b0
|
Provenance
The following attestation bundles were made for pytest_airflow_in_a_box-0.12.0.tar.gz:
Publisher:
release.yml on nredd/pytest-airflow-in-a-box
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_airflow_in_a_box-0.12.0.tar.gz -
Subject digest:
190e64db34c900a819d39424547ced3fffb6851a735b4aef7a4cb12dc838f298 - Sigstore transparency entry: 2595253300
- Sigstore integration time:
-
Permalink:
nredd/pytest-airflow-in-a-box@3a8ba47051d71dbbbe78804a10590c63ef4aaa1c -
Branch / Tag:
refs/tags/v0.12.0 - Owner: https://github.com/nredd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3a8ba47051d71dbbbe78804a10590c63ef4aaa1c -
Trigger Event:
release
-
Statement type:
File details
Details for the file pytest_airflow_in_a_box-0.12.0-py3-none-any.whl.
File metadata
- Download URL: pytest_airflow_in_a_box-0.12.0-py3-none-any.whl
- Upload date:
- Size: 406.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a841a6e2c305dcde31c75de59e7b4e776e625ce2a595a68573725c36ac260ac
|
|
| MD5 |
86cace73b5a07b165bab6d525128a266
|
|
| BLAKE2b-256 |
36a6514efe7a14cb735bbd02352adf08b482fea3721d5204b077f8ffc9c4e32d
|
Provenance
The following attestation bundles were made for pytest_airflow_in_a_box-0.12.0-py3-none-any.whl:
Publisher:
release.yml on nredd/pytest-airflow-in-a-box
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_airflow_in_a_box-0.12.0-py3-none-any.whl -
Subject digest:
4a841a6e2c305dcde31c75de59e7b4e776e625ce2a595a68573725c36ac260ac - Sigstore transparency entry: 2595253800
- Sigstore integration time:
-
Permalink:
nredd/pytest-airflow-in-a-box@3a8ba47051d71dbbbe78804a10590c63ef4aaa1c -
Branch / Tag:
refs/tags/v0.12.0 - Owner: https://github.com/nredd
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3a8ba47051d71dbbbe78804a10590c63ef4aaa1c -
Trigger Event:
release
-
Statement type: