Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Coverage.py branch coverage: execution paths are not correctness assertions

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

Branch coverage records which possible control-flow destinations were executed, while tests separately decide whether their results were correct.

Download Python source kit

Operation contract

The owned module has one negative-input branch and one accepted return. Tests execute both paths with explicit expected behavior, then coverage.py writes a JSON report. The program checks that no branch destination is missing. Module, report and measurement files all live in one temporary directory, and exact coverage totals are not printed as a portability promise.

Failure and ownership boundary

Full measured branch coverage can still accompany wrong assertions or an incomplete input contract. The fixture is a two-path local function, not coverage of the site or an entire service. Excluded lines and subprocesses also require deliberate configuration. Hypothesis property tests: compare generated cases with an independent contract and Python unittest.mock: inject a collaborator failure before publication extend testing beyond one percentage.

Tested environment

Dependency check: this program was executed on CPython 3.14.6 with coverage==7.16.2. Install these versions in a separate virtual environment. The download includes the recorded environment snapshot; no third-party package is part of the website runtime.

Working program

python
from pathlib import Path
import importlib.util
import json
import tempfile
import coverage

with tempfile.TemporaryDirectory() as directory:
    target = Path(directory) / "quantity_rules.py"
    target.write_text('def accept_quantity(quantity):\n    if quantity < 0:\n        raise ValueError("negative")\n    return quantity\n', encoding="utf-8")
    measured = coverage.Coverage(branch=True, data_file=str(Path(directory) / ".coverage"))
    measured.start()
    try:
        spec = importlib.util.spec_from_file_location("owned_quantity_rules", target)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        assert module.accept_quantity(3) == 3
        try:
            module.accept_quantity(-1)
        except ValueError:
            pass
        else:
            raise AssertionError("negative branch did not reject")
    finally:
        measured.stop()
    report = Path(directory) / "coverage.json"
    measured.json_report(outfile=str(report), include=[str(target)])
    details = json.loads(report.read_text(encoding="utf-8"))
    print("missing branches:", details["totals"]["missing_branches"])
print("measurement files owned by temporary directory")

Output

Output
missing branches: 0
measurement files owned by temporary directory

Costs and limits

Instrumentation adds execution and recording overhead; this fixture does not benchmark it. Source and control-flow analysis scale with measured code, while retained coverage data scales with recorded locations. A percentage must be interpreted against the actual measured files.

Common Mistakes

  • Coverage measures execution, not the strength of an assertion.
  • Do not report a tiny fixture’s percentage as whole-service coverage.

Connected lessons

Hypothesis property tests: compare generated cases with an independent contract, Python unittest.mock: inject a collaborator failure before publication, Pytest fixtures: isolated files and parameterized rejection tests.

Check the next state boundary

Python mutation testing: prove a suite rejects selected wrong implementations.

python
coverage-branches
Storage details