Test Coverage
The share of code executed by tests, and why 100% isn't the goal.
Also known as: code coverage, coverage, line coverage, branch coverage
Test coverage is the percentage of your code that runs while your tests run. A coverage tool marks which lines (or branches) were executed and which never were.
pytest --cov=myapp --cov-report=term-missing
# myapp/orders.py 85% missing: 42-47, 61
The report is useful in one direction: uncovered code is definitely untested. Lines 42-47 above are never run by any test, so a bug there would go unnoticed.
Why 100% isn’t the goal
The reverse isn’t true: covered code isn’t necessarily well tested. A test can run a line without checking anything about its result:
def test_total():
calculate_total(order) # runs the code, asserts nothing: still counts as covered
Chasing a number leads to useless tests written just to light up lines, and it distracts from tests that matter. When a measure becomes a target, people optimize the measure.
Line vs branch coverage
- Line coverage: was this line executed?
- Branch coverage: was each side of every
iftaken? It catches the case where only the “true” path is ever tested.
Using it well
- Look at what’s uncovered, especially important logic like payments or permissions.
- Use it to find gaps, not as proof of quality. A low number (say, under 50%) is a signal; a high one is not a guarantee.
- A common team practice is “don’t let coverage drop on a PR”, not “must hit 100%”.
- To check that your tests would actually catch bugs, see mutation testing.