Skip to main content
Beta: Front-End Checklist is currently in beta. Some issues are still being fixed. Thanks for your patience.
TestingMedium

Maintain test coverage thresholds

Set and enforce minimum code coverage thresholds to ensure adequate test coverage.

Utilities
Quick take
Typical fix time 15 min
  • Set global thresholds: 70% branches, 80% lines/functions/statements
  • Apply stricter thresholds (90%+) to critical utility code
  • Exclude generated code, type definitions, and config files
  • Focus on meaningful coverage—test behavior, not just lines
Why it matters: Coverage thresholds prevent code quality from degrading over time by failing builds when test coverage drops below safe levels.

Rule Details

Test coverage thresholds prevent code quality from degrading over time by failing builds when coverage drops below acceptable levels.

Code Example

// jest.config.js
module.exports = {
  collectCoverageFrom: [
    'src/**/*.{js,jsx,ts,tsx}',
    '!src/**/*.d.ts',
    '!src/**/*.stories.{js,jsx,ts,tsx}',
    '!src/**/index.{js,ts}' // Re-exports only
  ],
  coverageThreshold: {
    global: {
      branches: 70,
      functions: 80,
      lines: 80,
      statements: 80
    },
    // Stricter thresholds for critical code
    './src/utils/': {
      branches: 90,
      functions: 95,
      lines: 95,
      statements: 95
    }
  },
  coverageReporters: ['text', 'lcov', 'html']
}

Why It Matters

Coverage thresholds prevent code quality from degrading over time by failing builds when test coverage drops below safe levels.

Coverage TypeMinimumGoodExcellent
Statements60%80%90%+
Branches60%75%85%+
Functions70%85%95%+
Lines60%80%90%+

Vitest Configuration

// vitest.config.ts
import { defineConfig } from 'vitest/config'
 
export default defineConfig({
  test: {
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      thresholds: {
        lines: 80,
        branches: 70,
        functions: 80,
        statements: 80
      },
      exclude: [
        'node_modules/',
        'test/',
        '**/*.d.ts',
        '**/*.config.{js,ts}'
      ]
    }
  }
})

CI/CD Integration

GitHub Actions

name: Tests
on: [push, pull_request]
 
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: npm ci
      - run: npm test -- --coverage --coverageReporters=text-lcov > coverage.lcov
 
      # Upload to Codecov
      - uses: codecov/codecov-action@v4
        with:
          files: ./coverage.lcov
          fail_ci_if_error: true
 
      # Or upload to Coveralls
      - uses: coverallsapp/github-action@v2
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}

Best Practices

Focus on Meaningful Coverage

// ✅ Good: Test behavior, not just lines
test('validates email format', () => {
  expect(isValidEmail('user@example.com')).toBe(true)
  expect(isValidEmail('invalid')).toBe(false)
  expect(isValidEmail('')).toBe(false)
  expect(isValidEmail('user@.com')).toBe(false)
})
 
// ❌ Bad: Just hitting lines without meaningful assertions
test('calls isValidEmail', () => {
  isValidEmail('test@test.com')
  // No assertions!
})

Exclude Generated Code

// jest.config.js
collectCoverageFrom: [
  'src/**/*.{ts,tsx}',
  '!src/**/*.generated.ts',
  '!src/graphql/types.ts',
  '!src/**/__mocks__/**'
]

Verification

  1. Run the relevant test or CI step locally and confirm it fails when the rule is violated.
  2. Ensure the automation blocks regressions instead of only printing warnings.
  3. Cover at least one representative high-risk flow, component, or route.
  4. Keep thresholds or assertions in version control so changes remain reviewable.

Use with AI

Copy these prompts to use with your AI assistant, or install the MCP server to use directly from Claude, Cursor, or Windsurf.

Check

Verify implementation

Review this project's test coverage configuration to ensure minimum thresholds are set and enforced in CI/CD.

Fix

Auto-fix issues

Configure coverage thresholds in Jest, Vitest, or your testing framework, and add coverage checks to CI/CD.

Explain

Learn more

Explain how to set up test coverage thresholds and what coverage levels are appropriate for different types of code.

Review

Code review

Review tests, CI workflows, and enforcement points related to Maintain test coverage thresholds. Flag exact gaps where the rule is not automatically verified or where failures do not block regressions.

Sources

References used to support the guidance in this rule.

Further Reading

Tools and supplementary material for exploring the topic in more depth.

Playwright
playwright.devTool

Rules that often go hand-in-hand with this one.

Write unit tests

Critical functionality has unit tests with good coverage for reliability.

Testing
Write integration tests for key workflows

Test how multiple units of code work together — API routes with their database queries, form submissions with validation, and component trees with their state management.

Testing
Use mutation testing to measure how well tests detect bugs

Run Stryker mutation testing on critical business logic to verify that your test suite will actually catch real bugs, not just achieve line coverage.

Testing
Integrate real-time error monitoring in production

A real-time error monitoring service captures, groups, and alerts on unhandled exceptions and promise rejections in production so issues are discovered before users report them.

Testing

Was this rule helpful?

Your feedback helps improve rule quality. This stays internal for now.

Loading feedback...
0 / 385