What is code coverage, and is 100% a good target?
Quick Answer
Code coverage measures which lines/branches run during the test suite. It tells you what's definitely not tested, but not whether the tests are good — you can hit 100% with tests that assert nothing. Treat coverage as a floor (e.g. don't let it drop) and a way to find gaps, not a goal to chase.
Coverage tells me which code the tests actually executed. It's useful for finding blind spots — “nothing ever tests this branch” — but it says nothing about test quality, because I can run every line with a test that has no assertions. So I use it as a floor: CI fails if coverage drops, and I look at what's uncovered. I don't chase 100%, because that pushes you to write pointless tests for trivial code or to write assertion-free tests just to move the number. Mutation testing is a better measure of whether the tests would actually catch a bug.
- Line coverage — was the line executed. Branch coverage — was each
if/elsepath taken. Branch is more meaningful. - Chasing 100% leads to low-value tests for trivial code (getters, generated code) and gaming (tests without assertions).
- Better signals: mutation testing (Stryker) checks whether tests actually catch introduced bugs.
- In .NET: coverlet + ReportGenerator; enforce a threshold in CI but keep it realistic (e.g. 70–80% on the core).