Code Coverage Best Practices
Code Coverage Best Practices treat coverage as a way to find untested code, not a quality target to game. Emphasizing diff coverage and strong assertions keeps the metric honest and useful as code and migrations evolve.
Best Practice: Code Coverage Best Practices
Code coverage measures which lines, branches, or paths your tests execute. Used well, it highlights code that no test touches at all. Used poorly, it becomes a vanity metric that teams game with assertion-free tests. Google's guidance frames coverage as a tool to find untested code, not as a quality guarantee or a hard target. High coverage with weak assertions proves little, while moderate coverage with strong, behavior-focused assertions can be far more valuable. The most actionable form is diff (patch) coverage, which asks whether new and changed code is tested rather than chasing a global percentage.
Step-by-Step Implementation Guidance
- Enable coverage collection in your test runner and report line and branch coverage.
- Treat coverage as a discovery tool: review uncovered, high-risk code paths.
- Enforce diff coverage on pull requests so new code arrives tested.
- Avoid rigid global targets that incentivize meaningless tests.
- Pair coverage with assertion quality checks such as mutation testing on critical modules.
- Exclude generated code and trivial accessors to keep numbers meaningful.
- Publish trends to spot erosion early without punishing healthy refactors.
Common Mistakes Teams Make When Ignoring This Practice
- Setting a single high global target and writing assertion-free tests to hit it.
- Confusing coverage with correctness or test quality.
- Ignoring branch coverage and missing untested conditional paths.
- Counting generated or boilerplate code in the metric.
- Blocking refactors because a percentage dipped slightly.
Tools and Techniques That Support This Practice
- Coverage engines: JaCoCo, Coverage.py, Istanbul/nyc, Go cover.
- Diff/patch coverage gates: Codecov, Coveralls, SonarQube.
- Branch and condition coverage reporting.
- Mutation testing to validate assertion strength.
- CI integration to surface coverage on every pull request.
How This Practice Applies to Different Migration Types
- Cloud Migration: Use coverage to confirm portable logic is tested before relocating it.
- Database Migration: Check that data-access and mapping code paths are exercised on the new engine.
- SaaS Migration: Ensure adapter and integration code for the new provider is covered.
- Codebase Migration: Raise coverage of legacy code to form a safety net before refactoring.
Checklist
- Coverage collection reports both line and branch metrics.
- Coverage is used to find untested code, not as a sole target.
- Diff coverage is enforced on pull requests.
- Assertion quality is validated, not just execution.
- Generated and trivial code is excluded.
- Coverage trends are tracked over time.
- Refactoring is not blocked by minor percentage changes.