# Python coverage: coverage.py, SlipCover, and Supercov > Compare Python coverage tools: coverage.py with pytest-cov, SlipCover, and Supercov. See per-test contexts, MC/DC, and assertion coverage side by side. Web page: https://supercov.com/compare/python-code-coverage · Published 2026-09-13, updated 2026-10-12 All Supercov pages for agents: https://supercov.com/llms.txt · Full text: https://supercov.com/llms-full.txt ## Start with pytest-cov for line and branch coverage For an existing pytest project, coverage.py with pytest-cov is a straightforward starting point. pytest-cov connects coverage.py to pytest; it is not a second measurement engine. Install it in your project's Python environment, then measure your source: ```sh python -m pip install pytest-cov python -m pytest --cov=src --cov-branch --cov-report=term-missing ``` Replace `src` with your package or source directory. The report lists missed lines and partial branches. coverage.py's [branch guide](https://coverage.readthedocs.io/en/7.16.0/branch.html) explains how it records transitions between lines. To associate execution with individual pytest tests, add `--cov-context=test`. [pytest-cov supports per-test contexts](https://pytest-cov.readthedocs.io/en/latest/contexts.html), including setup, run and teardown. Supercov is not unique simply because it connects code with tests. If your project uses unittest, you can keep that runner: ```sh python -m coverage run --branch --source=src -m unittest discover python -m coverage report -m ``` ## Where SlipCover fits SlipCover is an alternative line and branch collector. It can launch pytest without a separate pytest coverage plugin: ```sh python -m pip install slipcover python -m slipcover --branch --source src -m pytest ``` Its [documentation](https://github.com/plasma-umass/slipcover/blob/v1.1.0/README.md) explains the collection approach and supported environments. If coverage overhead is your problem, compare it on your own suite with the same Python version, source scope and outputs. The small example below is not a speed test. ## Run the same pytest suite with all three tools [Download the comparison](https://supercov.com/downloads/supercov-coverage-comparisons.zip) and open its `python` folder. Use CPython 3.9 or newer; the recording used 3.13.1. Create a virtual environment and install the pinned packages: ```sh python3 -m venv .venv source .venv/bin/activate python -m pip install -r requirements.txt ``` On Windows, activate with `.venv\\Scripts\\Activate.ps1` instead. The requirements file belongs to this downloadable example, not to your existing project. Its source is: ```python def checkout(signed_in, expired, price, quantity): if signed_in and not expired: total = price * quantity return {"status": "confirmed", "total": total} return {"status": "denied", "total": 0} ``` Two pytest tests check the returned status for a valid session and a signed-out visitor. Neither checks an expired session or the calculated amount. ```sh python -m pytest --cov=src --cov-branch --cov-context=test --cov-report=term-missing python -m slipcover --branch --source src -m pytest supercov -- python -m pytest supercov runs latest ``` The coverage.py report includes: ```text Name Stmts Miss Branch BrPart Cover Missing ------------------------------------------------------------ src/session.py 5 0 2 0 100% ------------------------------------------------------------ TOTAL 5 0 2 0 100% ``` Here are the recorded results. coverage.py and SlipCover ran on September 14, 2026; Supercov's runs were repeated with 2.0.0 on September 25 and matched. Every run uses the same source and pytest tests. | Report | Lines | Branches | MC/DC | | --- | --- | --- | --- | | coverage.py 7.16.0 through pytest-cov 7.1.0 | 100% (5/5) | 100% (2/2) | Not reported | | SlipCover 1.1.0 | 100% (5/5) | 100% (2/2) | Not reported | | Supercov 2.0.0 wrapping pytest | 100% (5/5) | 100% (6/6) | 50% (1/2) | The tools use different branch models, hence the different denominators. That does not make one branch count more correct. MC/DC supplies a separate measurement: whether each condition independently changes the decision. ## Find the missing expiry test Query the checkout decision: ```sh supercov runs latest decision src/session.py:2 ``` The output includes: ```text signed_in and not expired C1 covered: signed_in C2 MISSING: not expired confidence executed vectors: TT -> T tests=1 confidence=executed F- -> F tests=1 confidence=executed ``` The signed-out test reaches the denied branch without evaluating the expiry condition. A signed-in customer with an expired session is the missing case: ```python def test_rejects_an_expired_session(): assert checkout(True, True, 25, 2)["status"] == "denied" ``` With that third case, the valid-session test and expired-session test show the expiry condition changing the result. The [MC/DC guide](https://supercov.com/docs/mcdc?language=python) walks through the comparison. ## Check the amount, not just the status A returned status does not establish that the total is right. The original tests still pass if the calculation subtracts 1 from the answer. A stronger assertion in the valid-session test is: ```python assert checkout(True, False, 25, 2) == {"status": "confirmed", "total": 50} ``` The download includes the completed suite in `completed-tests.txt`. Replace `tests/test_session.py` with its contents and rerun the same commands. | Check | Starter tests | Completed tests | | --- | --- | --- | | Tests against the original code | Pass: 2 tests | Pass: 3 tests | | Native line and branch coverage | 100% | 100% | | MC/DC | 50% (1/2) | 100% (2/2) | | Remove the expiry guard | Still pass | Fail | | Subtract 1 from the total | Still pass | Fail | Both faults were run separately. This demonstrates two specific missing checks, not a general mutation score. The [recording](https://supercov.com/downloads/coverage-comparisons-2026-09-14.json) includes commands, full output, source and tests. Assertions were not assessed here (the comparison was recorded with Supercov 2.0), so it reports no assertion-coverage percentage. [Assertion coverage](https://supercov.com/docs/assertions?language=python) is a separate step: `runs latest assertions assess` asks Jev which executed statements each test would catch a change to. ## Which tool should you keep? Use coverage.py and pytest-cov when line, branch and test-context reports answer your question. Consider SlipCover when evaluating collection overhead. Supercov adds independent-condition gaps and an assertion-review workflow without replacing pytest. | Feature | coverage.py 7.16.0 | SlipCover 1.1.0 | Supercov 4.3.0 | |---|---|---|---| | Code quality scoring | × Not built in | × Not built in | ✓ Supported | | Security review | × Not built in | × Not built in | ✓ Supported | | Line coverage | ✓ Supported | ✓ Supported | ✓ Supported | | Branch coverage | ✓ Supported | ✓ Supported | ✓ Supported | | MC/DC | × Not built in | × Not built in | ✓ Supported | | Per-test coverage | ✓ Supported | × Not built in | ✓ Supported | | Assertion coverage | × Not built in | × Not built in | ✓ Supported | | Reports | ✓ Supported | × Not built in | ✓ Supported | Standard coverage workflows in the versions shown; custom plugins are outside this table. Supercov measures CPython 3.9 and newer. pytest-cov uses coverage.py; enable test contexts for per-test coverage. Per-test coverage means individual tests, not just test files. Supercov needs a supported runner. Assertion coverage is Jev’s judgment, test by test, of whether changing each executed statement would make the test fail; it is not a mutation score or a correctness guarantee. Supercov measures CPython 3.9 or newer. See the [Python installation guide](https://supercov.com/docs/python.md). It is not the only Python MC/DC option: [pymcdc](https://pypi.org/project/pymcdc/0.2.6/) is a dedicated analyzer. Choosing between the pytest plugin and coverage.py itself? See [pytest-cov vs coverage.py](https://supercov.com/compare/pytest-cov-vs-coverage.md). None of these coverage percentages prove that the application meets its requirements. For checks outside source coverage, compare [QA tools for coding agents](https://supercov.com/compare/qa-tools-for-coding-agents.md). ## Feature sources - [coverage.py: Coverage and reports](https://coverage.readthedocs.io/en/7.16.0/) - [coverage.py: HTML report](https://coverage.readthedocs.io/en/7.16.0/cmd.html) - [coverage.py: Test contexts](https://coverage.readthedocs.io/en/7.16.0/contexts.html) - [coverage.py: pytest-cov integration](https://pytest-cov.readthedocs.io/en/latest/contexts.html) - [SlipCover: Coverage features](https://github.com/plasma-umass/slipcover/tree/v1.1.0) - [Supercov: Coverage model](https://github.com/supercorp-ai/supercov/blob/v4.3.0/docs/coverage-model.md) - [Supercov: Supported runners](https://github.com/supercorp-ai/supercov/blob/v4.3.0/docs/supported-suites.md) - [Supercov: Assertion coverage](https://github.com/supercorp-ai/supercov/blob/v4.3.0/docs/assertions.md) - [Supercov: Code quality](https://github.com/supercorp-ai/supercov/blob/v4.3.0/docs/quality.md) - [Supercov: Security](https://github.com/supercorp-ai/supercov/blob/v4.3.0/docs/security.md) - [Supercov: Reports](https://github.com/supercorp-ai/supercov/blob/v4.3.0/docs/reports.md) - [Supercov: CLI reference](https://github.com/supercorp-ai/supercov/blob/v4.3.0/docs/cli.md) Example evidence: [source, commands and full results (JSON)](https://supercov.com/downloads/coverage-comparisons-2026-09-14.json) · [runnable examples (ZIP)](https://supercov.com/downloads/supercov-coverage-comparisons.zip). Measured September 14, 2026; Supercov runs repeated with 2.0.0 on September 25, unchanged. Same-runner fixtures, not a performance benchmark or a general conformance test.