pytest-delta
A pytest plugin that runs only the tests affected by your code changes. Instead of running your entire test suite every time, pytest-delta uses content hashing and AST-based dependency analysis to figure out which tests actually need to run.
How It Works
-
On the first run, all tests execute normally. pytest-delta builds a dependency graph by parsing imports across your Python files and saves a snapshot (file hashes + graph) to a
.delta.msgpackfile. -
On subsequent runs, it compares current file hashes against the snapshot to detect changes. Using the reverse dependency graph, it identifies all files transitively affected by those changes and runs only the corresponding tests.
-
If a
conftest.pychanges, all tests in its directory and subdirectories are re-run (conservative approach). -
The delta file is only updated when all tests pass. If tests fail, the previous snapshot is preserved so those tests run again next time.
Installation
pip install pytest-delta
Or with Poetry:
poetry add pytest-delta
Usage
Enable the plugin with the --delta flag:
# First run: executes all tests, creates .delta.msgpack
pytest --delta
# Second run: no changes detected, exits 0 immediately
pytest --delta
# After modifying src/utils.py: only affected tests run
pytest --delta
Use --delta-debug to see what the plugin is doing:
pytest --delta --delta-debug
[pytest-delta] Plugin enabled
[pytest-delta] Loaded delta: 42 files tracked
[pytest-delta] Changed: 1, New: 0, Deleted: 0
[pytest-delta] Affected test files: 3
[pytest-delta] tests/test_api.py
[pytest-delta] tests/test_models.py
[pytest-delta] tests/test_utils.py
[pytest-delta] Selected: 12, Deselected: 85
CLI Options
| Option | Description |
|---|---|
--delta |
Enable delta-based test filtering |
--delta-file PATH |
Custom delta file path (default: .delta.msgpack) |
--delta-rebuild |
Force rebuild the dependency graph from scratch |
--delta-no-save |
Don't save the delta file after the run (read-only mode) |
--delta-debug |
Print debug information about filtering decisions |
Markers
Force specific tests to always run regardless of changes:
import pytest
@pytest.mark.delta_always
def test_smoke():
"""This test runs every time, even if nothing changed."""
assert app.health_check() == "ok"
CI Workflow
A typical workflow:
- Developer runs
pytest --deltalocally. Tests pass,.delta.msgpackis updated. - Developer commits the delta file along with their changes.
- CI runs
pytest --delta. Since the delta file reflects the already-validated state, no tests need to run and CI exits 0 immediately.
For CI pipelines where you want to prevent accidental delta file updates:
pytest --delta --delta-no-save
Change Detection
pytest-delta uses content hashing (SHA-256) to detect changes. This means:
- No dependency on git history or commit hashes
- Works with uncommitted and staged changes
- No issues with rebasing or squash merges
- Detects changes regardless of how they were made
Dependency Analysis
The plugin builds a dependency graph by parsing Python AST import statements:
- Handles absolute imports (
import pkg.mod,from pkg.mod import func) - Handles relative imports (
from .utils import helper,from ..core import Base) - Tracks
__init__.pyas implicit dependencies of package modules - Computes transitive closure: if A imports B and B imports C, changing C re-runs tests for both A and B
Limitations:
- Only tracks
.pyfiles (non-Python config/data files are ignored) - Dynamic imports (
importlib.import_module()) are not detected - Only project-local imports are tracked (third-party packages are ignored)
Configuration
Add .delta.msgpack to your .gitignore if you don't want to share the delta file across developers, or commit it if you want the CI optimization described above.
# Uncomment to exclude from version control
# .delta.msgpack
License
MIT
Metadata
Release files for pytest-delta 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_delta-2.0.0.tar.gz | 8.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_delta-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.0 kB
Release files / pytest_delta-2.0.0.tar.gz
| Download URL | pytest_delta-2.0.0.tar.gz |
|---|---|
| Size | 8.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4a922fe607ee52114b158bfee8bba83ad84c27cfed7267c041d9e087f4da1a88
|
|
BLAKE2b-256 checksum How to use checksums |
1bea29b6e5e5d777fd449aedcf7377e4ab42e32d226b4403c6c2e8cafd632de2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.2.0 CPython/3.9.18 Darwin/25.2.0
|
Release files / pytest_delta-2.0.0-py3-none-any.whl
| Download URL | pytest_delta-2.0.0-py3-none-any.whl |
|---|---|
| Size | 10.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
11e6aee760d6cac7e94571475e2d0c542a3568b0a36c7cf3781e743a2bf64b2f
|
|
BLAKE2b-256 checksum How to use checksums |
b8ee224bd3d88f724b799100cad6bcb096b6af53cf64497bf1aaf568256e7f12
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.2.0 CPython/3.9.18 Darwin/25.2.0
|