Day 2 of 5

Automated Testing in CI

Running tests in CI catches regressions before they reach production. Today you will run Jest unit tests, upload coverage reports, and fail the build when coverage drops below a threshold.

yaml
# .github/workflows/test.yml
name: Test

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci

      - name: Run tests with coverage
        run: npm test -- --coverage --coverageReporters=lcov

      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          files: ./coverage/lcov.info
          fail_ci_if_error: true

      - name: Check coverage threshold
        run: |
          COVERAGE=$(node -e "
            const c = require('./coverage/coverage-summary.json');
            console.log(c.total.lines.pct);
          ")
          echo "Line coverage: $COVERAGE%"
          node -e "if ($COVERAGE < 80) { console.error('Coverage below 80%'); process.exit(1); }"
json
{
  "scripts": {
    "test": "jest --passWithNoTests"
  },
  "jest": {
    "coverageThreshold": {
      "global": {
        "lines": 80,
        "functions": 80,
        "branches": 70
      }
    }
  }
}

Exercise: Add Coverage Enforcement

  1. Write at least 3 Jest unit tests for a utility function
  2. Add the --coverage flag to your test script
  3. Configure coverageThreshold in jest.config.js
  4. Add the Codecov action to your workflow
  5. Break a test and confirm the CI run turns red

Day 2 Summary

Finished this lesson?