Test Coverage

Test coverage measures how much of your code is actually exercised when the test suite runs. It's a useful diagnostic — it pinpoints code no test touches — but it's frequently misused as a quality target. The crucial distinction: coverage tells you what code ran, not whether your tests verified anything meaningful about it.

The healthy way to use coverage is as a flashlight, not a scoreboard: run it to find untested critical paths and error handlers, hold the line so coverage doesn't silently erode, and resist the urge to chase 100% by writing assertions that prove nothing.

TL;DR

Quick Example

Generate a coverage report and read it for gaps, not for the headline number:

Core Concepts

Coverage metrics

💡 Branch coverage matters most: 100% line coverage can still miss the else of a condition. A test can run a line without ever exercising both outcomes.

Limitations

Running Coverage

JavaScript (Jest / Vitest)

Python (pytest-cov)

Coverage in CI

Set a floor and fail builds that drop below it:

Track trends over time with Codecov or Coveralls, and fail when coverage decreases:

Finding & Excluding Code

Use the HTML report to spot red (unexecuted) lines and untaken branches — especially error-handling paths, which tests routinely miss:

Exclude genuinely untestable code explicitly:

Best Practices

Common Mistakes

Writing tests just to hit 100%

Treating the percentage as quality

FAQ

What coverage percentage should I aim for?

There's no magic number. A common practice is ~80% as a CI floor for general code, ~90–95% for critical business logic, and lower for utilities/glue. But the percentage is a means, not the goal — covering the right code (core logic, branches, error paths) well matters far more than a high overall figure padded with trivial tests.

Why isn't 100% coverage a good goal?

Because the last stretch usually means writing low-value tests for trivial or defensive code, and 100% line coverage still doesn't guarantee your assertions are meaningful — code can run without being verified. Chasing 100% trades real effort for a vanity metric and can even encourage hollow tests. Aim for high coverage of what matters, not totality.

What's the difference between line and branch coverage?

Line coverage counts which lines executed; branch coverage counts whether each decision path (both the if and the else) was taken. Branch coverage is stricter and more informative — you can have 100% line coverage while never testing the false branch of a condition. Prefer branch coverage as your primary metric for conditional-heavy code.

Does high coverage mean my tests are good?

No. Coverage only measures what code ran during tests, not whether the tests checked the right things. A suite can hit 95% coverage with weak or missing assertions. To gauge whether tests actually catch regressions, look at assertion quality and consider mutation testing, which deliberately introduces bugs to see if your tests notice.

Related Topics

References