easyEngineering Practices#76

Test coverage thresholds

Prompt

Configure Jest to enforce coverage thresholds in jest.config.js: 80% for branches, functions, lines, and statements.

Solution

module.exports = {
  collectCoverage: true,
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },
  },
}
Mentor's take

A coverage threshold is a quality gate: the build fails when coverage drops below the line, which turns "we should write tests" from a culture hope into a CI precondition. Without the gate, coverage only ever ratchets down — every rushed PR shaves a percent and nobody notices until the number is meaningless.

Know what the four metrics actually measure: statements and lines are near-duplicates (was this code executed), functions catches entirely untested helpers, and branches is the one that earns its keep — 100% line coverage can still miss every else, and branch coverage is what exposes the untested error path.

The senior caveats: coverage measures execution, not assertion quality — a test that calls everything and asserts nothing scores perfectly, which is why the number is a floor, not a goal. And a global threshold punishes the wrong people: it blocks today's PR because of debt written years ago. The stronger pattern, which SonarQube-class gates formalize, is thresholds on new code — old debt is grandfathered, new debt is stopped at the door. Jest approximates this with per-directory thresholds on the modules you're actively hardening.

Red flag: chasing 100% — the last percentiles buy assertion-free tests written to satisfy the meter.

Say it: "Coverage is a floor enforced in CI, not a goal — I gate on branches, not lines, and prefer thresholds on new code so the gate stops new debt instead of relitigating old debt."