GitLab: Enable coverage reporting with pytest
GitLab supports coverage reporting. There are essential two types of coverage:
- Total coverage, which is a single percentage displayed next to a job (or in Merge Requests, or badges).
- Detailed coverage, which is a line-by-line coverage visualisation.
Following are the steps for configuring pytest to generate coverage statistics, and hook both of these coverage types up to GitLab.
Update tox.ini
to generate terminal and XML coverage §
Assuming your Python package is called my_package
, update your pytest call in tox.ini
to use --cov-report
as follows:
The important parts are:
- For the total coverage:
--cov-report=term
- to print the coverage out to stdout. This will be parsed by GitLab to display the total coverage percentage in the GitLab UI.
- For the detailed coverage:
--cov-report=xml:<dir>
- to write the coverage out in XML format. This will be used for detailed coverage reports in the GitLab UI.
Update .gitlab-ci.yml
to generate coverage artifacts §
Then, in .gitlab-ci.yml
, use the coverage_report
field with the following configuration to get GitLab to extract the coverage:
The coverage_report
is a special field used by GitLab Covertura Coverage to extract the coverage results.1
The important parts are:
- For the total coverage:
coverage: <regex>
- this defines the regex used to extract the total coverage percentage from stdout.
- For the detailed coverage:
artifacts: ... reports: ... coverage_report:
- this provides the coverage report to GitLab.path: '<dir>'
- this must be the same directory as intox.ini
.
For example, your stdout might look like:
Then the regex is extracting the line starting with TOTAL
.2
Bonus: separate coverage directory for each Python version §
We can use $(echo $CI_JOB_NAME | cut -d : -f 2)
to extract the Python version from the job name. For example, this will convert unit_test:py310
to py310
.
This can be useful if you wish to have a separate coverage directory for each Python version:
At time of writing, GitLab supports two types of detailed overage: Cobertura and JaCoCo. These notes use Cobertura. ↩︎
The GitLab documentation includes many example regexes, including one for pytest, but it did not manage to match for my pytest output. ↩︎