pytest-dag
Documentation: https://pytest-dag.readthedocs.io/en/latest/
pytest-dag is a pytest plugin for dependency-aware test execution.
It lets tests declare dependencies, builds a DAG, runs tests in topological order, and skips downstream tests when required dependencies fail.
Installation
pip install pytest-dag
Quick Start
import pytest
def test_a():
assert True
@pytest.mark.dag(depends=["test_a"])
def test_b():
assert True
@pytest.mark.dag(depends=["test_b"])
def test_c():
assert True
@pytest.mark.dag(depends=["test_b"])
def test_d():
assert True
Expected run order:
test_a -> test_b -> (test_c, test_d)
If test_a fails, dependent tests are skipped with a clear reason:
SKIPPED pytest-dag: blocked by test_file.py::test_a (FAILED)
Marker Syntax
# Single dependency (string)
@pytest.mark.dag(depends="test_login")
def test_profile():
...
# Multiple dependencies (list)
@pytest.mark.dag(depends=["test_login", "test_db_connect"])
def test_dashboard():
...
# Cross-file dependency (full nodeid)
@pytest.mark.dag(depends=["tests/auth/test_auth.py::test_login"])
def test_profile():
...
YAML DAG (for larger test suite, where it really shine!)
For larger suites, you can define dependencies in YAML instead of (or in addition to) markers.
pyproject.toml:
[tool.pytest.ini_options]
dag_file = "tests/dag.yaml"
tests/dag.yaml:
nodes:
- id: tests/test_flow.py::test_a
- id: tests/test_flow.py::test_b
depends: [tests/test_flow.py::test_a]
- id: tests/test_flow.py::test_c
depends: [tests/test_flow.py::test_b]
Marker dependencies and YAML dependencies are unioned.
CLI Options
| Option | Tier | Default | Description |
|---|---|---|---|
--dag-block-on-outcomes OUTCOMES |
Free+ | fail |
Outcomes that block dependents: fail, skip, xfail, error |
--dag-print-graph |
Free+ | off | Print DAG order and edges after collection |
--pytest-dag-license-key |
— | unset | Provide license key directly |
--pytest-dag-license-key-file |
— | unset | Read license key from file |
--dag-workers N |
Pro | 1 | Run DAG-independent tests in parallel |
--dag-report-out PATH |
Pro | unset | Write interactive HTML DAG report to PATH |
Examples:
# Cascade skipping (skip dependents when a dependency fails or is skipped)
pytest --dag-block-on-outcomes fail,skip
# Print computed graph for debugging
pytest --dag-print-graph
Migrating from pytest-dependency
If your suite uses pytest.mark.dependency(...) markers, the built-in migration
tool scans your tests, emits a dag.yaml, and removes the old markers from
source files in one step.
| Option | Default | Description |
|---|---|---|
--migrate-from-pytest-dependency |
off | Run preflight validation, emit dag.yaml, remove pytest.mark.dependency markers from source, then exit without running tests |
--dag-file-out PATH |
tests/dag.yaml |
Output path for the generated YAML file |
--migrate-dry-run |
off | Preview the generated YAML without writing any files |
Example workflow:
# Step 1: Preview what will be generated (no files written)
pytest --migrate-from-pytest-dependency --migrate-dry-run
# Step 2: Run the full migration (writes dag.yaml, removes old markers)
pytest --migrate-from-pytest-dependency --dag-file-out tests/dag.yaml
Tiers
pytest-dag is free to use with no key required. A pro license unlocks additional features.
| Feature | Free | Pro |
|---|---|---|
| DAG enforcement, ordering, skip propagation | ✓ | ✓ |
| YAML DAG file | ✓ | ✓ |
| Max DAG nodes | 25 | Unlimited |
| Max DAG depth | 7 | Unlimited |
Parallel workers (--dag-workers) |
— | ✓ |
HTML report (--dag-report-out) |
— | ✓ |
| Run banner | shown | silent |
Activating pro
Set the key received from the purchase page via environment variable (recommended for CI):
export PYTEST_DAG_LICENSE_KEY=<your-license-key>
pytest --dag-report-out report.html --dag-workers 4
Or via CLI flag or key file:
pytest --pytest-dag-license-key <your-license-key>
pytest --pytest-dag-license-key-file /path/to/key.txt
License verification is done locally — no network calls are made.
Purchase: https://slrsoft.ca/app/pytest-dag/purchase
Support: support@slrsoft.ca
Viewing Skip Reasons
Use -v -rs to see exact skip reasons:
pytest -v -rs
Example summary:
SKIPPED [2] pytest-dag: blocked by test_demo.py::test_login (FAILED)
SKIPPED [1] test_demo.py:104: feature not yet implemented
pytest-xdist Compatibility
On the free tier, pytest-dag automatically disables pytest-xdist (-n)
to preserve DAG ordering correctness, and prints a warning.
On the pro tier, use --dag-workers N for native DAG-aware parallelism.
If xdist is installed but -n is not passed, behaviour is unchanged.
Troubleshooting
plugins: ... dag-0.1.0 (not pytest-dag-0.1.0)
This is normal. Pytest shortens plugin names in output by dropping the
pytest- prefix.
Plugin not loading in a virtualenv
If which pytest points to a global executable after activating a venv, use:
python -m pytest ...
This guarantees the venv interpreter and installed plugin are used.
License
Proprietary. Copyright (c) 2026 SLR Software Solutions Inc.
See the license terms in the repository LICENSE file.
Licensing inquiries: support@slrsoft.ca
Metadata
Release files for pytest-dag 3.14.15
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pytest_dag-3.14.15.tar.gz | 45.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_dag-3.14.15-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.2 kB
Release files / pytest_dag-3.14.15.tar.gz
| Download URL | pytest_dag-3.14.15.tar.gz |
|---|---|
| Size | 45.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
73f901852d13944a7a3973456b88ca6af7287506f3bffc2f42db4d7a174aa486
|
|
BLAKE2b-256 checksum How to use checksums |
561e5ccd3b36853455c2efd454c7b6bfc5021759ecc4809a5bb7eaaae42d6de6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / pytest_dag-3.14.15-py3-none-any.whl
| Download URL | pytest_dag-3.14.15-py3-none-any.whl |
|---|---|
| Size | 36.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
52aa8a18193998c4bbb86fbe0d911ea6ee58556309c9552056a3c4f2f339da05
|
|
BLAKE2b-256 checksum How to use checksums |
0e2710cc8490e63aff673e8ef26eb1d218dcae3f93975cefade3cd320305a63b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for pytest-dag 3.14.15
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.