Skip to content

Coverage & Reporting

Coverage instruments your code to count which parts executed while the tests ran. Reporting turns that raw data into something a human reads: tables, charts, CI artefacts and dashboards over time.

Run the tests
│
▼
Instrument code ──► record lines/branches/functions that ran
│
▼
Generate report ──► local HTML + CI artefact + dashboard
│
▼
Thresholds ──► pass/fail the build

Common coverage types:

Type Measures Catches
Line Which lines ran Dead code, untouched branches
Branch Whether every if/else path was taken Conditions never fully exercised
Function Which functions were called Forgotten APIs
Statement Which statements ran Similar to line

Use it for

  • Finding regions of code no test ever touches
  • CI thresholds to stop coverage sliding backwards over time
  • Stakeholder reporting: trends, not just an absolute number
  • Focusing on branch coverage where the code has many conditions

Avoid or reduce it when

  • Chasing a 100% target as a metric (coverage only says what ran)
  • Using coverage to judge quality instead of mutation testing
  • Enabling coverage on every CI job, slowing the build for a report nobody reads
Tool Ecosystem Notes
Istanbul / nyc JS/TS The classic coverage tool, HTML/lcov output
c8 JS/TS Uses Node’s native V8 coverage, fast
JaCoCo Java/JVM Bytecode coverage; Maven/Gradle integration
coverage.py Python The Python standard; --branch for branch coverage
go cover Go Built in; go tool cover -html
Allure Cross-language Polished test reports across many languages
ReportPortal Cross-language Analytics dashboards, flaky tracking over time
Terminal window
npm install -D @vitest/coverage-v8
npx vitest run --coverage
vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
coverage: {
provider: 'v8',
reporter: ['text', 'lcov', 'html'],
thresholds: { lines: 80, branches: 70 },
},
},
});
  • Set thresholds as a ratchet. Prevent regressions rather than forcing 100%.
  • Prefer branch coverage in condition-heavy code; line coverage is easy to game.
  • Exclude generated code from reports so the numbers mean something.
  • Publish reports as CI artefacts and keep history to see trends, not snapshots.
  • Coverage is not quality. A line that ran may have no assertion checking it — pair it with mutation testing.
  • Have one consolidated report. Do not scatter a separate dashboard per language.

Self-assessment quiz

Pick one answer per question, then press Check answers.

  1. What does branch coverage measure?
  2. Why is 100% coverage not the same as being well tested?
  3. Which coverage tool uses Node's native V8 coverage?
  4. What are Allure and ReportPortal mainly used for?
  5. What is a sound way to set a coverage threshold in CI?