Skip to content
Join Now Login

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.

FormatStatusFile Extension
LCOVSupportedlcov.info, .lcov
Cobertura XMLSupportedcoverage.xml, cobertura.xml
JaCoCo XMLSupportedjacoco.xml
Clover XMLSupportedclover.xml

Use the standard Upload API to send coverage files. The only difference is the file type being uploaded.

FieldRequiredDescription
filesYesYour coverage file (e.g., coverage/lcov.info, coverage.xml)
tags.commitShaRecommendedGit commit SHA for tracking coverage per commit
tags.branchRecommendedGit branch name for filtering coverage by branch
tags.typeOptionalSet to "coverage" for clarity
curl
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"}'

Most test frameworks support LCOV output. Here’s how to configure common tools:

vitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
coverage: {
provider: 'v8',
reporter: ['lcov', 'text'],
reportsDirectory: './coverage'
}
}
})

Run tests with: pnpm vitest --coverage

jest.config.js
module.exports = {
collectCoverage: true,
coverageReporters: ['lcov', 'text'],
coverageDirectory: './coverage'
}

Run tests with: pnpm jest --coverage

Install pytest-cov: pip install pytest-cov

pyproject.toml
[tool.pytest.ini_options]
addopts = "--cov=src --cov-report=lcov:coverage/lcov.info"

Run tests with: pytest

.github/workflows/test.yml
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.yml
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.xml

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

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:

ModeBehavior
Always Pass (default)Posts coverage as an informational status. The check always passes regardless of the coverage value.
ThresholdFails the status if coverage is below a configured percentage (e.g., 80%). Useful for enforcing a minimum coverage floor.
DeltaFails 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.

MetricDescription
Line CoveragePercentage of executable lines covered by tests
Branch CoveragePercentage of code branches (if/else) covered
Function CoveragePercentage of functions called during tests
  • 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
  • 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)
  • Some tools report different metrics - Gaffer uses the LCOV-reported values
  • Verify source maps are correctly configured if using transpiled code