pytest-cov
01 / 02

pytest-cov: Branch Coverage, Config & CI Workflow

pytest-cov: Branch Coverage, Config & CI Workflow

Branch Coverage

def classify(x):
    if x > 0:
        return 'positive'
    else:
        return 'non-positive'

# Line coverage is satisfied as soon as the `if` line executes once --
# even if every test only ever passes a positive x, so the `else`
# branch is NEVER actually exercised.
def test_classify_positive():
    assert classify(5) == 'positive'
# Branch coverage specifically flags that the else path was never
# taken -- a stricter, more thorough signal than line coverage alone
pytest --cov=mypackage --cov-branch --cov-report=term-missing

Project Configuration

# pyproject.toml -- centralizes flags so every plain `pytest`
# invocation automatically runs with coverage, without contributors
# needing to remember a long CLI flag string
[tool.pytest.ini_options]
addopts = "--cov=mypackage --cov-report=term-missing --cov-fail-under=80"

[tool.coverage.run]
branch = true
omit = [
    "*/migrations/*",
    "*/tests/*",
]

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "if TYPE_CHECKING:",
]

Auto-generated files like migrations rarely reflect hand-tested application logic -- omitting them keeps the coverage percentage meaningful rather than padded by boilerplate.

Excluding Specific Lines

if TYPE_CHECKING:  # pragma: no cover
    from mymodule import SomeClass  # never executes at runtime

def handle(status):
    if status == 'ok':
        return process()
    else:
        raise AssertionError('unreachable')  # pragma: no cover

Parallel Test Runs (pytest-xdist)

# pytest-cov aggregates coverage data collected from multiple worker
# processes into a single combined report -- works correctly alongside
# pytest-xdist's -n flag for distributing tests across processes
pytest --cov=mypackage -n 4

# When a suite is deliberately split across multiple separate pytest
# invocations (e.g. by marker, across CI matrix jobs), combine results
# instead of overwriting the previous .coverage data file
pytest --cov=mypackage --cov-append -m unit
pytest --cov=mypackage --cov-append -m integration

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free