Coverage Reports (Beta)
Gaffer can track your code coverage metrics alongside your test results. Upload coverage reports to see coverage trends, identify gaps, and monitor improvements over time.
Supported Formats
Section titled “Supported Formats”| Format | Status | File Extension |
|---|---|---|
| LCOV | Supported | lcov.info, .lcov |
| Cobertura XML | Supported | coverage.xml, cobertura.xml |
| JaCoCo XML | Supported | jacoco.xml |
| Clover XML | Supported | clover.xml |
Upload API
Section titled “Upload API”Use the standard Upload API to send coverage files. The only difference is the file type being uploaded.
| Field | Required | Description |
|---|---|---|
files | Yes | Your coverage file (e.g., coverage/lcov.info, coverage.xml) |
tags.commitSha | Recommended | Git commit SHA for tracking coverage per commit |
tags.branch | Recommended | Git branch name for filtering coverage by branch |
tags.type | Optional | Set to "coverage" for clarity |
Example Request
Section titled “Example Request”curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: YOUR_UPLOAD_TOKEN" \ -F "files=@coverage/lcov.info" \ -F 'tags={"commitSha":"abc123","branch":"main","type":"coverage"}'Generating LCOV Reports
Section titled “Generating LCOV Reports”Most test frameworks support LCOV output. Here’s how to configure common tools:
Vitest
Section titled “Vitest”import { defineConfig } from 'vitest/config'
export default defineConfig({ test: { coverage: { provider: 'v8', reporter: ['lcov', 'text'], reportsDirectory: './coverage' } }})Run tests with: pnpm vitest --coverage
module.exports = { collectCoverage: true, coverageReporters: ['lcov', 'text'], coverageDirectory: './coverage'}Run tests with: pnpm jest --coverage
pytest
Section titled “pytest”Install pytest-cov: pip install pytest-cov
[tool.pytest.ini_options]addopts = "--cov=src --cov-report=lcov:coverage/lcov.info"Run tests with: pytest
CI Integration
Section titled “CI Integration”GitHub Actions
Section titled “GitHub Actions”name: Tests with Coverage
on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Run tests with coverage run: pnpm test --coverage
- name: Upload coverage to Gaffer run: | curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: ${{ secrets.GAFFER_TOKEN }}" \ -F "files=@coverage/lcov.info" \ -F 'tags={"commitSha":"${{ github.sha }}","branch":"${{ github.ref_name }}","type":"coverage"}'GitLab CI
Section titled “GitLab CI”test: stage: test script: - pnpm test --coverage - | curl -X POST https://app.gaffer.sh/api/upload \ -H "X-API-Key: $GAFFER_TOKEN" \ -F "files=@coverage/lcov.info" \ -F "tags={\"commitSha\":\"$CI_COMMIT_SHA\",\"branch\":\"$CI_COMMIT_REF_NAME\",\"type\":\"coverage\"}" artifacts: reports: coverage_report: coverage_format: cobertura path: coverage/cobertura-coverage.xmlViewing Coverage
Section titled “Viewing Coverage”Once you’ve uploaded coverage reports, you can view them in the Gaffer dashboard:
- Project Analytics - See coverage trends over time in the analytics tab
- Test Run Details - View coverage associated with specific test runs
- File Breakdown - Drill down into per-file coverage metrics
GitHub Commit Status Gating
Section titled “GitHub Commit Status Gating”Gaffer can report coverage as a GitHub commit status on pull requests, optionally failing the status if coverage doesn’t meet your criteria. This requires the Gaffer GitHub App installed and a repository linked to your project (configured under Project Settings > GitHub).
Configure this at Project Settings > GitHub > Coverage Status Settings. Three modes are available:
| Mode | Behavior |
|---|---|
| Always Pass (default) | Posts coverage as an informational status. The check always passes regardless of the coverage value. |
| Threshold | Fails the status if coverage is below a configured percentage (e.g., 80%). Useful for enforcing a minimum coverage floor. |
| Delta | Fails the status if coverage drops by more than a configured percentage compared to the default branch (e.g., fails if coverage decreases by more than 5%). Useful for preventing regressions without requiring a fixed minimum. |
You can choose which metric to gate on: line coverage or branch coverage.
Delta mode compares the PR’s coverage against the most recent coverage data from the repository’s default branch. If no default branch coverage exists yet, it falls back to the most recent coverage report from any branch. If no previous coverage data exists at all, the delta check passes.
Metrics Tracked
Section titled “Metrics Tracked”| Metric | Description |
|---|---|
| Line Coverage | Percentage of executable lines covered by tests |
| Branch Coverage | Percentage of code branches (if/else) covered |
| Function Coverage | Percentage of functions called during tests |
Best Practices
Section titled “Best Practices”- Upload with every test run - Consistent uploads enable accurate trend tracking
- Include commit SHA - Links coverage to specific code changes
- Set a baseline - Track coverage over time to catch regressions
- Focus on meaningful coverage - High coverage doesn’t always mean quality tests
Troubleshooting
Section titled “Troubleshooting”No coverage data showing
Section titled “No coverage data showing”- Verify the coverage file exists and contains data
- Check that the file uses a supported format (LCOV, Cobertura, JaCoCo, or Clover)
- Ensure the upload request succeeded (check for 201 response)
Coverage seems incorrect
Section titled “Coverage seems incorrect”- Some tools report different metrics - Gaffer uses the LCOV-reported values
- Verify source maps are correctly configured if using transpiled code
Next Steps
Section titled “Next Steps”- Upload API Reference - Full API documentation
- Analytics & Metrics - Understanding your test metrics
- Live Demo - See coverage tracking in action