This episode covers test coverage in Jest: enabling coverage reports, understanding line, branch, function, and statement coverage, setting thresholds as a quality gate, and using coverage to maintain code quality in CI.

How much of your code is actually tested? Test coverage is the quantitative answer to that question — the percentage of code that gets executed while the suite runs. Episode 10 covers how to enable coverage reports in Jest, understand its four main metrics, set thresholds as a quality gate, and use them to maintain quality continuously.
It's important to understand the limitation up front: high coverage doesn't guarantee good tests, but low coverage almost certainly means a lot of untested code. This episode teaches you to use coverage as a tool, not a meaningless number to chase.
The fastest way to produce a coverage report is the --coverage flag:
npx jest --coverageThe command npx jest --coverage runs the suite while measuring execution coverage. When it finishes, Jest prints a summary to the terminal and writes an HTML report in the coverage/ directory — open coverage/lcov-report/index.html in a browser to explore per-file coverage.
Add options to jest.config.js so coverage is always enabled when needed:
module.exports = {
collectCoverage: true,
collectCoverageFrom: [
"src/**/*.js",
"!src/**/*.test.js",
],
coverageDirectory: "coverage",
coverageProvider: "v8",
};collectCoverageFrom determines which files are measured, and the ! pattern excludes the test files themselves. coverageProvider: "v8" uses the V8 engine, which is faster than the default Istanbul.
Jest reports four different metrics:
Branch coverage is the one most often low because it demands testing both sides of a branch. For example, if (nilai > 10) requires two tests — one with a value above 10 and one below — to reach 100 percent branch coverage.
File | % Stmts | % Branch | % Funcs | % Lines
api.js | 82.35 | 66.66 | 88.88 | 82.35
utils.js | 100.00 | 100.00 | 100.00 | 100.00To keep coverage from silently dropping, set a minimum threshold. If the numbers fall below it, Jest fails the suite:
module.exports = {
coverageThreshold: {
global: {
branches: 80,
functions: 85,
lines: 85,
statements: 85,
},
"./src/utils/**/*.js": {
lines: 95,
},
},
};coverageThreshold accepts a global threshold and per-file-pattern thresholds. The line global: { lines: 85 } means the entire project must have at least 85 percent line coverage — below that, the Jest command exits with an error code.
Thresholds are most useful when enforced in CI. By including the --coverage --coverageThreshold flags in your pipeline, a coverage drop fails the build before the code is merged. This becomes an automated quality gate that doesn't rely on individual discipline.
Use coverage reports to find blind spots:
Coverage is meant to guide, not replace thinking. A file with 100 percent coverage can still contain tests that test nothing.
More important than today's numbers is the long-term trend. Record coverage at every release, and investigate sudden drops — they usually signal new code without tests or a refactor that removed coverage. Many teams display a coverage badge in the README; episode 14 will cover how to publish it from CI.
Episode 10 covered test coverage as a measurement tool and a quality gate: enabling reports with --coverage, understanding the four metrics, setting thresholds enforced in CI, and using reports to find blind spots.
Key takeaways:
npx jest --coverage produces a report and HTML files in coverage/.coverageThreshold fails the suite when numbers fall below the threshold.In the next episode, episode 11, we'll cover configuration & environment management — options like testEnvironment and setupFiles, environment variables for test runs, custom setup files and global helpers, and organizing configuration across projects.