Code Coverage
Generate coverage reports, set thresholds, and improve meaningful test coverage.
Coverage Reports
Run jest --coverage to collect statement, branch, function, and line coverage. HTML report in coverage/lcov-report highlights untested lines.
Coverage indicates executed code, not correct behavior—high coverage with weak assertions gives false security.
npx jest --coverage --coverageReporters=text-summary --coverageReporters=lcov
Coverage Thresholds
coverageThreshold in Jest config fails CI when coverage drops below global or per-path minimums. Enforce gradually—ratchet thresholds up as coverage improves.
Per-directory thresholds protect critical modules (billing, auth) with stricter bars than utility folders.
export default {
coverageThreshold: {
global: { branches: 80, functions: 80, lines: 80, statements: 80 },
"./src/auth/": { branches: 90, lines: 95 },
},
};Improving Coverage Meaningfully
Prioritize branch coverage on error paths and edge cases—uncaught else branches often hide bugs. Test boundary values, empty inputs, and concurrent scenarios.
Delete dead code instead of writing tests solely to satisfy metrics. Refactor untestable code to inject dependencies.
- Review uncovered lines in PR diffs with coverage comments in CI
- Pair coverage reports with mutation testing for assertion strength
- Focus on business-critical paths over boilerplate re-exports
Excluding Code
collectCoverageFrom globs specify which files to include; prefix with ! to exclude. Ignore generated code, config files, and type-only modules.
Istanbul ignore comments (/* istanbul ignore next */) document intentionally untested lines—use sparingly with justification.
collectCoverageFrom: [
"src/**/*.{ts,tsx}",
"!src/**/*.d.ts",
"!src/**/index.ts",
]CI Integration
Upload lcov to Codecov, Coveralls, or SonarQube for PR annotations. Fail builds on threshold regression.
Diff coverage tools highlight whether new lines in PR are tested—more actionable than global percentage alone.
- Run coverage on CI only for main branches if speed critical—still run tests always
- Cache Jest results in CI with caution—coverage must reflect current code
- Separate unit and integration coverage reports for clearer ownership