Skip to main content

A pytest plugin that enforces test execution order via a dependency DAG

Project description

pytest-dag

pytest-dag logo

pytest-dag banner

Docs status

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

Project details


Download files

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

Source Distribution

pytest_dag-3.14.15.tar.gz (45.9 kB view details)

Uploaded Source

Built Distribution

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

pytest_dag-3.14.15-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file pytest_dag-3.14.15.tar.gz.

File metadata

  • Download URL: pytest_dag-3.14.15.tar.gz
  • Upload date:
  • Size: 45.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for pytest_dag-3.14.15.tar.gz
Algorithm Hash digest
SHA256 73f901852d13944a7a3973456b88ca6af7287506f3bffc2f42db4d7a174aa486
MD5 1f702c98ecc45be8bdd687f42644a053
BLAKE2b-256 561e5ccd3b36853455c2efd454c7b6bfc5021759ecc4809a5bb7eaaae42d6de6

See more details on using hashes here.

File details

Details for the file pytest_dag-3.14.15-py3-none-any.whl.

File metadata

  • Download URL: pytest_dag-3.14.15-py3-none-any.whl
  • Upload date:
  • Size: 36.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for pytest_dag-3.14.15-py3-none-any.whl
Algorithm Hash digest
SHA256 52aa8a18193998c4bbb86fbe0d911ea6ee58556309c9552056a3c4f2f339da05
MD5 7c4799271896ed1ae0ce16a0fd3866cc
BLAKE2b-256 0e2710cc8490e63aff673e8ef26eb1d218dcae3f93975cefade3cd320305a63b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page