Cobertura coverage visualization

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

Use Cobertura XML reports to display line-by-line coverage annotations in merge request diffs. GitLab reads the Cobertura XML report and annotates each changed line as covered (green), not covered (red), or loaded but never executed (orange). GitLab includes reports from any job in any stage in the pipeline.

Coverage visualization uses the artifacts:reports:coverage_report keyword. It does not display a coverage percentage in the MR widget or populate coverage history graphs. To display a coverage percentage, configure the coverage keyword separately.

The Cobertura XML format was originally developed for Java, but most coverage frameworks support it through plugins or built-in exporters:

Example CI/CD configurations

The following examples show how to configure CI/CD jobs for different programming languages. You can also see a working example in the coverage-report demonstration project.

JavaScript example

The following .gitlab-ci.yml example uses Mocha and nyc to generate the coverage artifact:

test:
  script:
    - npm install
    - npx nyc --reporter cobertura mocha
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

Java and Kotlin examples

GitLab 17.6 and later supports JaCoCo format natively. For new projects, use native JaCoCo reports.

The following examples use the jacoco2cobertura Docker image to convert JaCoCo reports to Cobertura format.

Maven example

The test-jdk11 job uses Maven to generate a JaCoCo XML artifact. The coverage-jdk11 job converts it to Cobertura format:

test-jdk11:
  stage: test
  image: maven:3.6.3-jdk-11
  script:
    - mvn $MAVEN_CLI_OPTS clean org.jacoco:jacoco-maven-plugin:prepare-agent test jacoco:report
  artifacts:
    paths:
      - target/site/jacoco/jacoco.xml

coverage-jdk11:
  # The `visualize` stage does not exist by default.
  # Define it first, or use an existing stage like `deploy`.
  stage: visualize
  image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.11
  script:
    # Convert report from JaCoCo to Cobertura, using relative project path
    - python /opt/cover2cover.py target/site/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/
        > target/site/cobertura.xml
  needs: ["test-jdk11"]
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: target/site/cobertura.xml

Gradle example

The test-jdk11 job uses Gradle to generate a JaCoCo XML artifact. The coverage-jdk11 job converts it to Cobertura format:

test-jdk11:
  stage: test
  image: gradle:6.6.1-jdk11
  script:
    - gradle test jacocoTestReport # JaCoCo must be configured to create an XML report
  artifacts:
    paths:
      - build/jacoco/jacoco.xml

coverage-jdk11:
  # The `visualize` stage does not exist by default.
  # Define it first, or use an existing stage like `deploy`.
  stage: visualize
  image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.11
  script:
    # Convert report from JaCoCo to Cobertura, using relative project path
    - python /opt/cover2cover.py build/jacoco/jacoco.xml $CI_PROJECT_DIR/src/main/java/
        > build/cobertura.xml
  needs: ["test-jdk11"]
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: build/cobertura.xml

Python example

The following .gitlab-ci.yml example uses pytest-cov to collect test coverage data:

run tests:
  stage: test
  image: python:3
  script:
    - pip install pytest pytest-cov
    - pytest --cov --cov-report term --cov-report xml:coverage.xml
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml

PHP example

The following .gitlab-ci.yml example uses PHPUnit to collect test coverage data and generate the report.

With a minimal phpunit.xml file (you can reference this example repository), you can run the tests and generate coverage.xml:

run tests:
  stage: test
  image: php:latest
  variables:
    XDEBUG_MODE: coverage
  before_script:
    - apt-get update && apt-get -yq install git unzip zip libzip-dev zlib1g-dev
    - docker-php-ext-install zip
    - pecl install xdebug && docker-php-ext-enable xdebug
    - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
    - php composer-setup.php --install-dir=/usr/local/bin --filename=composer
    - composer install
    - composer require --dev phpunit/phpunit phpunit/php-code-coverage
  script:
    - php ./vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage.cobertura.xml
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage.cobertura.xml

Codeception, through PHPUnit, also supports generating a Cobertura report with run. The path for the generated file depends on the --coverage-cobertura option and paths configuration for the unit test suite. Configure .gitlab-ci.yml to find Cobertura in the appropriate path.

C/C++ example

The following .gitlab-ci.yml example for C/C++ with gcc or g++ uses gcovr to generate the coverage output file in Cobertura XML format.

This example assumes:

  • The Makefile is created by cmake in the build directory, in another job in a previous stage. If you use automake to generate the Makefile, call make check instead of make test.
  • cmake (or automake) has set the compiler option --coverage.
run tests:
  stage: test
  script:
    - cd build
    - make test
    - gcovr --xml-pretty --exclude-unreachable-branches --print-summary -o coverage.xml --root ${CI_PROJECT_DIR}
  artifacts:
    name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
    expire_in: 2 days
    reports:
      coverage_report:
        coverage_format: cobertura
        path: build/coverage.xml

Go example

The following .gitlab-ci.yml example uses:

This example assumes Go modules are being used. The -covermode count option does not work with the -race flag. To generate code coverage while also using -race, switch to -covermode atomic, which is slower.

run tests:
  stage: test
  image: golang:1.17
  script:
    - go install
    - go test ./... -coverprofile=coverage.txt -covermode count
    - go get github.com/boumenot/gocover-cobertura
    - go run github.com/boumenot/gocover-cobertura < coverage.txt > coverage.xml
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml

Ruby example

The following .gitlab-ci.yml example uses:

This example assumes:

  • bundler is used for dependency management, with rspec, simplecov, and simplecov-cobertura added to your Gemfile.
  • CoberturaFormatter has been added to your SimpleCov.formatters configuration in spec_helper.rb.
run tests:
  stage: test
  image: ruby:3.1
  script:
    - bundle install
    - bundle exec rspec
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/coverage.xml

Troubleshooting

For troubleshooting coverage visualization, including path resolution failures, file size limits, and annotations not appearing, see coverage visualization troubleshooting.