Skip to main content

Test Coverage and Metrics

Created: May 8, 2026 Larry Qu 3 min read

Test coverage measures how much code is tested. This article covers coverage metrics and best practices.

Introduction

Test coverage provides:

  • Code quality metrics
  • Testing completeness
  • Risk identification
  • Quality gates
  • Improvement tracking

Understanding coverage helps you:

  • Measure test completeness
  • Identify untested code
  • Set quality targets
  • Improve code quality
  • Track progress

Coverage Types

Line Coverage

// ✅ Good: Line coverage
function calculateTotal(items) {
  let total = 0;           // Line 1
  for (const item of items) { // Line 2
    total += item.price;   // Line 3
  }
  return total;            // Line 4
}

// Test covers all lines
test('calculates total', () => {
  expect(calculateTotal([{ price: 10 }, { price: 20 }])).toBe(30);
});

Branch Coverage

// ✅ Good: Branch coverage
function getDiscount(amount) {
  if (amount > 100) {      // Branch 1
    return 0.1;
  } else if (amount > 50) { // Branch 2
    return 0.05;
  } else {                  // Branch 3
    return 0;
  }
}

// Test all branches
test('returns 10% discount for amount > 100', () => {
  expect(getDiscount(150)).toBe(0.1);
});

test('returns 5% discount for amount > 50', () => {
  expect(getDiscount(75)).toBe(0.05);
});

test('returns no discount for amount <= 50', () => {
  expect(getDiscount(30)).toBe(0);
});

Function Coverage

// ✅ Good: Function coverage
function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

function multiply(a, b) {
  return a * b;
}

// Test all functions
test('add function', () => {
  expect(add(2, 3)).toBe(5);
});

test('subtract function', () => {
  expect(subtract(5, 3)).toBe(2);
});

test('multiply function', () => {
  expect(multiply(2, 3)).toBe(6);
});

Coverage Configuration

Jest Coverage

// ✅ Good: Jest coverage config
// jest.config.js
module.exports = {
  collectCoverageFrom: [
    'src/**/*.js',
    '!src/index.js',
    '!src/**/*.test.js',
    '!src/**/__mocks__/**'
  ],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80
    },
    './src/utils/': {
      branches: 90,
      functions: 90,
      lines: 90,
      statements: 90
    }
  },
  coverageReporters: ['text', 'lcov', 'html']
};

// Run coverage
npm test -- --coverage

Coverage Reports

# ✅ Good: Generate coverage report
npm test -- --coverage

# ✅ Good: View HTML report
open coverage/lcov-report/index.html

# ✅ Good: Generate JSON report
npm test -- --coverage --coverageReporters=json

# ✅ Good: Upload to Codecov
npm install --save-dev codecov
codecov

Coverage Metrics

Measuring Coverage

// ✅ Good: Track coverage metrics
const coverageMetrics = {
  lines: 85,
  branches: 80,
  functions: 90,
  statements: 85
};

// ✅ Good: Set targets
const targets = {
  lines: 80,
  branches: 75,
  functions: 80,
  statements: 80
};

// ✅ Good: Check if targets met
function checkCoverage(metrics, targets) {
  for (const [key, value] of Object.entries(targets)) {
    if (metrics[key] < value) {
      console.error(`${key} coverage ${metrics[key]}% below target ${value}%`);
      return false;
    }
  }
  return true;
}

Best Practices

  1. Set realistic targets:
    // ✅ Good: Realistic targets
    coverageThreshold: {
      global: {
        lines: 80,
        branches: 75,
        functions: 80
      }
    }
    
    // ❌ Bad: Unrealistic targets
    coverageThreshold: {
      global: {
        lines: 100,
        branches: 100,
        functions: 100
      }
    }
    ```javascript
    
  2. Focus on critical code:
    // ✅ Good: Higher coverage for critical code
    './src/utils/': {
      lines: 95,
      branches: 90
    },
    './src/components/': {
      lines: 80,
      branches: 75
    }
    
    // ❌ Bad: Same coverage for all code
    ```javascript
    
  3. Exclude generated code:
    // ✅ Good: Exclude generated code
    collectCoverageFrom: [
      'src/**/*.js',
      '!src/**/*.generated.js',
      '!src/**/__mocks__/**'
    ]
    
    // ❌ Bad: Include everything
    collectCoverageFrom: ['src/**/*.js']
    

Summary

Test coverage is important. Key takeaways:

  • Measure coverage types
  • Set realistic targets
  • Focus on critical code
  • Exclude generated code
  • Track metrics
  • Improve incrementally
  • Use coverage reports
  • Maintain quality gates

Next Steps

Resources

Comments

Share this article

Scan to read on mobile