Types of Coverage
Code Coverage
Measures which lines, branches, and functions of source code are executed by automated tests.
Metrics:
- Line coverage: Percentage of code lines executed
- Branch coverage: Percentage of conditional branches (if/else, switch) taken
- Function coverage: Percentage of functions called
- Statement coverage: Percentage of statements executed
Requirements Coverage
Measures which business requirements have corresponding test cases.
Requirements Traceability Matrix (RTM):
| Requirement | Test Cases | Status |
|---|---|---|
| REQ-001: User login | TC-001, TC-002, TC-003 | 3/3 covered |
| REQ-002: Password reset | TC-010, TC-011 | 2/2 covered |
| REQ-003: Two-factor auth | — | NOT covered |
Code Coverage Tools
| Tool | Languages | Integration |
|---|---|---|
| Istanbul/nyc | JavaScript/TypeScript | Jest, Mocha, Vitest |
| JaCoCo | Java | Maven, Gradle, Jenkins |
| coverage.py | Python | pytest, unittest |
| SimpleCov | Ruby | RSpec, Minitest |
| SonarQube | Multi-language | CI/CD dashboards |
Reading Coverage Reports
A typical coverage report shows:
File | % Stmts | % Branch | % Funcs | % Lines |
------------------------|---------|----------|---------|---------|
src/auth/login.js | 95.2 | 88.0 | 100.0 | 95.0 |
src/auth/register.js | 78.3 | 62.5 | 85.7 | 77.1 |
src/payment/checkout.js | 45.0 | 30.0 | 50.0 | 44.2 |
src/utils/helpers.js | 100.0 | 100.0 | 100.0 | 100.0 |
How to interpret:
login.jsat 95% is well-testedregister.jsat 78% — branch coverage at 62.5% is a gapcheckout.jsat 45% is critically undertested for a payment modulehelpers.jsat 100% is fully covered (but small utility files are easy)
Setting Coverage Targets
Meaningful Targets
| Code Area | Suggested Target | Rationale |
|---|---|---|
| Payment/financial | 90%+ | High business risk |
| Authentication/security | 90%+ | Security critical |
| Core business logic | 80%+ | Primary functionality |
| API endpoints | 80%+ | Integration points |
| UI components | 60-70% | Visual testing complements |
| Utilities/helpers | 70%+ | Shared code, high reuse |
| Configuration/setup | 50%+ | Less critical |
The Coverage Trap
Do not chase 100% coverage blindly. Problems with obsessing over coverage numbers:
- Writing meaningless tests — tests that execute code without asserting outcomes
- Testing trivial code — getters, setters, configuration that adds no value
- Ignoring quality — high coverage with weak assertions is worse than lower coverage with strong assertions
- Neglecting other testing — exploratory, performance, security testing matters too
The right approach: Focus on critical paths, business logic, and risk areas. Use coverage reports to identify untested areas, not as a competition for the highest number.
Coverage in CI/CD
Quality Gates
Configure CI/CD to enforce minimum coverage:
# Example: GitHub Actions with coverage check
- name: Run tests with coverage
run: npm test -- --coverage
- name: Check coverage threshold
run: |
npx nyc check-coverage --lines 80 --branches 70 --functions 80
Coverage Trends
Track coverage over time. Coverage should never decrease after a PR merge. SonarQube’s “New Code” coverage ensures new code meets standards even if legacy code is below target.
Exercise: Analyze a Coverage Report
Given this coverage report for an e-commerce application, identify the risks and recommend actions:
Module | Line | Branch | Function |
--------------------|-------|--------|----------|
cart/add-to-cart | 92% | 85% | 100% |
cart/checkout | 38% | 22% | 45% |
cart/coupon | 75% | 60% | 80% |
user/registration | 88% | 80% | 95% |
user/authentication | 95% | 92% | 100% |
payment/process | 42% | 30% | 50% |
payment/refund | 15% | 10% | 20% |
admin/dashboard | 65% | 50% | 70% |
Solution
Critical Risks:
payment/processat 42% — payment processing is the highest-risk module. 30% branch coverage means most error handling paths are untested.payment/refundat 15% — critically undertested. Refund bugs cause direct financial loss and customer complaints.cart/checkoutat 38% — checkout is the revenue path. Bugs here mean lost sales.
Recommendations:
- Immediate (P1): Increase
payment/processto 85%+ andpayment/refundto 80%+. Financial modules must have strong coverage. - This sprint (P2): Increase
cart/checkoutto 80%+. Focus on branch coverage — the 22% means most conditional logic (error handling, edge cases) is not tested. - Next sprint (P3): Increase
cart/couponbranch coverage from 60% to 75%+. Coupon edge cases (expired, minimum order, combination rules) are common bug sources. - Set quality gate: New code in payment and checkout modules must have 85%+ coverage. Block PRs that decrease coverage in these modules.
- No action needed:
user/authenticationandcart/add-to-cartare well-covered.admin/dashboardat 65% is acceptable for admin features.
Key Takeaways
- Code coverage measures test execution; requirements coverage measures business requirement mapping
- Branch coverage is more valuable than line coverage — it reveals untested conditional logic
- Focus coverage targets on risk: payment and security modules need 90%+, utilities can be lower
- Do not chase 100% — focus on meaningful assertions over executed lines
- Use CI/CD quality gates to prevent coverage regression
- Coverage reports identify gaps — they are diagnostic tools, not goals in themselves