tldr: Test coverage metrics measure what proportion of your code or requirements is covered by tests. The common ones are line, branch, condition, path, and requirements coverage. High coverage does not guarantee quality, but very low coverage almost always correlates with shipping bugs.
What "coverage" actually means
Test coverage is a quantitative answer to a vague question: how much of the system has been tested?
The vagueness shows up in the dozen different metrics that all claim to measure coverage. They are not the same metric. Each measures a different "what" and is gamed in different ways.
Code coverage metrics
Line coverage
The simplest. What percentage of source code lines were executed by at least one test?
Easy to measure. Easy to game by writing trivial tests that touch lines without verifying their behavior.
Useful as a floor: below 50% line coverage on a non-trivial codebase usually means undertested. Above 80%, the metric stops being useful.
Branch coverage
Tracks both branches of every conditional. If your code has if (x) { A } else { B }, you need tests that hit both A and B for full branch coverage.
Stricter than line coverage. A line of code with a conditional can be 100% line-covered but 50% branch-covered if only one path is exercised.
Condition coverage
For compound conditions like if (a && b), condition coverage tracks each individual operand, not just the final outcome. Both a and b need to be true and false at some point.
More granular than branch coverage. Used in safety-critical software (aerospace, automotive).
Path coverage
Every possible execution path through the code. Quickly explodes combinatorially: a function with 10 conditionals can have over 1,000 paths.
Mostly theoretical. Used in research and very high-assurance code.
Requirements coverage
A different axis: not what code is exercised, but what requirements are tested.
Maintained as a requirements traceability matrix mapping each requirement to one or more test cases. The percentage of requirements with at least one passing test is the requirements coverage.
This is the most useful coverage metric for product teams. Code coverage tells you the engineering side is thorough. Requirements coverage tells you the team is testing what the business asked for.
The metrics that do not work
Test count. "We have 5,000 tests" tells you nothing. A team with 500 well-designed tests beats a team with 5,000 trivial ones.
Lines of test code. Same problem. Larger does not mean better.
Code-to-test ratio. A 1:1 ratio of test code to product code is sometimes cited as ideal. There is no evidence this number predicts quality.
Coverage percentage as a goal. Setting "we will have 80% coverage by Q3" causes teams to write tests that hit lines without testing behavior. Coverage as a measurement is fine. Coverage as a target gets gamed.
What metrics actually correlate with quality
Three signals correlate with shipping fewer bugs.
Escaped defect rate. Bugs found in production divided by total bugs found. The single best quality metric. See escaped defects.
Mean time to detection. How quickly are introduced bugs found?
Test pass rate trend. Is the suite stable or is it getting flakier?
These tell you whether your testing is working. Coverage tells you whether your testing exists.
How to instrument coverage
Code coverage tools are built into most language ecosystems.
- JavaScript: Istanbul (nyc), c8.
- Python: coverage.py.
- Java: JaCoCo.
- Go: built into
go test -cover. - Rust: cargo-tarpaulin, llvm-cov.
Most CI systems integrate these natively. Reports get generated per build, trends get tracked over time.
For requirements coverage, test management tools (TestRail, Zephyr, Xray) maintain the traceability matrix. Smaller teams use spreadsheets or markdown tables in the repo.
How AI testing changes the coverage picture
Traditional code coverage measures what unit and integration tests touch. AI testing tools run end-to-end flows, which exercise the entire stack but do not produce traditional code coverage numbers.
What they produce instead is something more useful: which user-facing flows are tested. Bug0 tracks flow coverage per release: the percentage of critical paths exercised by the test suite. This is closer to what the business actually cares about.
The two coverage views (code and flow) complement each other. Code coverage tells engineering the implementation is tested. Flow coverage tells the business the product is tested.
FAQs
What is a good code coverage percentage?
Depends on the project. A reasonable starting target is 70 to 80% line coverage and 60 to 70% branch coverage. Beyond 90%, marginal coverage rarely catches new bugs.
Should we enforce coverage thresholds in CI?
Yes, but loosely. A threshold prevents coverage from collapsing. A strict threshold encourages bad tests. "Cannot drop more than 2% from the previous build" works better than "must hit 85%."
Is requirements coverage more important than code coverage?
For product teams, yes. Code coverage tells you the engineering work is thorough. Requirements coverage tells you the right things are being tested.
How does flow coverage compare?
Flow coverage measures user-facing test thoroughness. It is often more meaningful than code coverage for product teams because it maps directly to user impact.
How does Bug0 measure coverage?
Bug0 reports flow coverage per release as part of its done-for-you QA service: which critical user flows have automated tests, which do not, and which are flaking. Pair with code coverage from your unit/integration suite for a full picture.
