Docs

Python coverage

Use pytest with coverage.py XML output. The XML report is Cobertura-compatible and can be uploaded directly.

Install dependencies

python -m pip install pytest pytest-cov coverage

Generate coverage

pytest --cov=src --cov-report=xml:coverage.xml

GitHub Actions workflow

Add COVERAGE_UPLOAD_TOKEN as a GitHub secret before running this workflow. The action uses the default upload endpoint unless you provide an optional endpoint override.

name: coverage

on:
  pull_request:
  push:

jobs:
  coverage:
    if: github.event_name == 'pull_request' || github.ref_name == github.event.repository.default_branch
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: python -m pip install -r requirements.txt
      - run: python -m pip install pytest pytest-cov coverage
      - run: pytest --cov=src --cov-report=xml:coverage.xml
      - name: Upload coverage
        uses: 9to5/9to5-coverage-action@v1
        with:
          token: ${{ secrets.COVERAGE_UPLOAD_TOKEN }}
          path: coverage.xml

Pull request behavior

The Cobertura XML is parsed into file-level coverage, project coverage, and patch coverage for the pull request.

Troubleshooting

If paths do not match changed files, run coverage from the repository root and keep source paths relative to the checkout.