pytest-cov-affected
A pytest plugin that runs only the tests for source modules you changed and reports coverage exclusively for those modules.
Why
Running the full test suite and full coverage report on every change is slow
and the resulting coverage number is diluted by code you didn't touch. With
--cov-affected, pytest collects only tests/<rel>/test_<module>.py for the
src/<pkg>/<rel>/<module>.py files in your local staged/unstaged changes. If
the tree is clean, it falls back to comparing against the merge-base with
main. Any subsequent coverage html / coverage xml reports contain rows
only for those modules.
--cov is optional and does not change the affected set.
Install
uv add --dev pytest-cov-affected
# or
pip install pytest-cov-affected
Usage
# run only tests for modules changed in local edits, or since merge-base with main
pytest --cov-affected
# show the coverage table without needing `--cov`
pytest --cov-affected --cov-report term-missing
# optional: also enable pytest-cov terminal reporting
pytest --cov-affected --cov
# pick a different diff base
pytest --cov-affected --cov-affected-base=origin/release
# include new untracked .py files under src/
pytest --cov-affected --cov-affected-include-untracked
# follow up with coverage reports — these will only contain affected modules
coverage html
coverage xml
Convention
The plugin assumes the standard src/ layout:
src/<package>/path/to/module.py ⇒ tests/path/to/test_module.py
Configurable via:
--cov-affected-src-root(default:src)--cov-affected-tests-root(default:tests)
Source files without a matching test file produce a UserWarning and are
counted in the summary line — they don't fail the run.
How it works
- Local staged/unstaged changes are checked first; if any exist, their changed
.pyfiles undersrc_rootbecome the affected set. - If there are no local changes,
git diffagainst the configured base produces the list of changed.pyfiles undersrc_root. - Each path is mapped to its expected test file; missing tests are reported.
- Pytest's collection is narrowed to the matching test files only.
- The active
coverage.pyinstance'sincludepatterns are constrained to the affected sources so measurement is scoped, or a managed coverage session is started whenpytest-covis not active. - At session end, the
.coverageSQLite data file is filtered in place so latercoverage html/coverage xmlcalls report only affected modules. A.coveragerc.affectedsidecar is written alongside for users who prefercoverage --rcfile.
Documentation
See docs/:
Development
uv sync
uv run pytest
Release files for pytest-cov-affected 0.1.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_cov_affected-0.1.0.tar.gz | 86.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_cov_affected-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 98.0 kB
Release files / pytest_cov_affected-0.1.0.tar.gz
| Download URL | pytest_cov_affected-0.1.0.tar.gz |
|---|---|
| Size | 86.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0711eddc938e39c2964d8b7a0ba3ac5a3a33cddfa78393e5fab4e115f558d566
|
|
BLAKE2b-256 checksum How to use checksums |
0cbe1fcb13ef8eadb1d405326f0e2f5ae9c03936667be6f77283ca3e06a1cf92
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 3, 2026.
Transparency logRelease files / pytest_cov_affected-0.1.0-py3-none-any.whl
| Download URL | pytest_cov_affected-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f8edef81ab6dc73d40326502256eae4c7b486480561fc3eeb11299bd43f6f18f
|
|
BLAKE2b-256 checksum How to use checksums |
dc099cf7a8205119d17b88d5156eb5c2004782dc8602daadc2df55177ba1a79b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 3, 2026.
Transparency log