10 KiB
		
	
	
	
	
	
			
		
		
	
	| stage | group | info | type | 
|---|---|---|---|
| Verify | Testing | To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments | reference, howto | 
Test Coverage Visualization
- Introduced in GitLab 12.9.
 - Feature flag removed in GitLab 13.5.
 
With the help of GitLab CI/CD, you can collect the test coverage information of your favorite testing or coverage-analysis tool, and visualize this information inside the file diff view of your merge requests (MRs). This will allow you to see which lines are covered by tests, and which lines still require coverage, before the MR is merged.
How test coverage visualization works
Collecting the coverage information is done via GitLab CI/CD's artifacts reports feature. You can specify one or more coverage reports to collect, including wildcard paths. GitLab then takes the coverage information in all the files and combines it together.
For the coverage analysis to work, you have to provide a properly formatted
Cobertura XML report to
artifacts:reports:cobertura.
This format was originally developed for Java, but most coverage analysis frameworks
for other languages have plugins to add support for it, like:
- simplecov-cobertura (Ruby)
 - gocover-cobertura (Golang)
 
Other coverage analysis frameworks support the format out of the box, for example:
- Istanbul (JavaScript)
 - Coverage.py (Python)
 
Once configured, if you create a merge request that triggers a pipeline which collects coverage reports, the coverage is shown in the diff view. This includes reports from any job in any stage in the pipeline. The coverage displays for each line:
covered(green): lines which have been checked at least once by testsno test coverage(orange): lines which are loaded but never executed- no coverage information: lines which are non-instrumented or not loaded
 
Hovering over the coverage bar provides further information, such as the number of times the line was checked by tests.
NOTE:
A limit of 100 <source> nodes for Cobertura format XML files applies. If your Cobertura report exceeds
100 nodes, there can be mismatches or no matches in the merge request diff view.
Artifact expiration
By default, the pipeline artifact used to draw the visualization on the merge request expires one week after creation.
Automatic class path correction
- Introduced in GitLab 13.8.
 - Feature flag removed in GitLab 13.9.
 
The coverage report properly matches changed files only if the filename of a class element
contains the full path relative to the project root. However, in some coverage analysis frameworks,
the generated Cobertura XML has the filename path relative to the class package directory instead.
To make an intelligent guess on the project root relative class path, the Cobertura XML parser
attempts to build the full path by:
- Extracting a portion of the 
sourcepaths from thesourceselement and combining them with the classfilenamepath. - Checking if the candidate path exists in the project.
 - Using the first candidate that matches as the class full path.
 
Path correction example
As an example, a project with:
- 
A full path of
test-org/test-project. - 
The following files relative to the project root:
Auth/User.cs Lib/Utils/User.cs src/main/java 
In the:
- 
Cobertura XML, the
filenameattribute in theclasselement assumes the value is a relative path to the project's root:<class name="packet.name" filename="src/main/java" line-rate="0.0" branch-rate="0.0" complexity="5"> - 
sourcesfrom Cobertura XML, the following paths in the format<CI_BUILDS_DIR>/<PROJECT_FULL_PATH>/...:<sources> <source>/builds/test-org/test-project/Auth</source> <source>/builds/test-org/test-project/Lib/Utils</source> </sources> 
The parser:
- Extracts 
AuthandLib/Utilsfrom thesourcesand uses these to determine theclasspath relative to the project root. - Combines these extracted 
sourcesand the class filename. For example, if there is aclasselement with thefilenamevalue ofUser.cs, the parser takes the first candidate path that matches, which isAuth/User.cs. - For each 
classelement, attempts to look for a match for each extractedsourcepath up to 100 iterations. If it reaches this limit without finding a matching path in the file tree, the class is not included in the final coverage report. 
NOTE:
Automatic class path correction only works on source paths in the format <CI_BUILDS_DIR>/<PROJECT_FULL_PATH>/....
The source is ignored if the path does not follow this pattern. The parser assumes that the
filename of a class element contains the full path relative to the project root.
Example test coverage configurations
JavaScript example
The following gitlab-ci.yml example uses Mocha
JavaScript testing and nyc coverage-tooling to
generate the coverage artifact:
test:
  script:
    - npm install
    - npx nyc --reporter cobertura mocha
  artifacts:
    reports:
      cobertura: coverage/cobertura-coverage.xml
Java and Kotlin examples
Maven example
The following gitlab-ci.yml example for Java or Kotlin uses Maven
to build the project and JaCoCo coverage-tooling to
generate the coverage artifact.
You can check the Docker image configuration and scripts if you want to build your own image.
GitLab expects the artifact in the Cobertura format, so you have to execute a few
scripts before uploading it. The test-jdk11 job tests the code and generates an
XML artifact. The coverage-jdk-11 job converts the artifact into a Cobertura report:
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:
  # Must be in a stage later than test-jdk11's stage.
  # The `visualize` stage does not exist by default.
  # Please define it first, or choose an existing stage like `deploy`.
  stage: visualize
  image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
  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"]
  dependencies:
    - test-jdk11
  artifacts:
    reports:
      cobertura: target/site/cobertura.xml
Gradle example
The following gitlab-ci.yml example for Java or Kotlin uses Gradle
to build the project and JaCoCo coverage-tooling to
generate the coverage artifact.
You can check the Docker image configuration and scripts if you want to build your own image.
GitLab expects the artifact in the Cobertura format, so you have to execute a few
scripts before uploading it. The test-jdk11 job tests the code and generates an
XML artifact. The coverage-jdk-11 job converts the artifact into a Cobertura report:
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:
  # Must be in a stage later than test-jdk11's stage.
  # The `visualize` stage does not exist by default.
  # Please define it first, or chose an existing stage like `deploy`.
  stage: visualize
  image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
  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"]
  dependencies:
    - test-jdk11
  artifacts:
    reports:
      cobertura: build/cobertura.xml
Python example
The following gitlab-ci.yml example for Python uses pytest-cov to collect test coverage data and coverage.py to convert the report to use full relative paths.
The information isn't displayed without the conversion.
This example assumes that the code for your package is in src/ and your tests are in tests.py:
run tests:
  stage: test
  image: python:3
  script:
    - pip install pytest pytest-cov
    - pytest --cov=src/ tests.py
    - coverage xml
  artifacts:
    reports:
      cobertura: coverage.xml
C/C++ example
The following gitlab-ci.yml example for C/C++ with
gcc or g++ as the compiler uses gcovr to generate the coverage
output file in Cobertura XML format.
This example assumes:
- That the 
Makefileis created bycmakein thebuilddirectory, within another job in a previous stage. (If you useautomaketo generate theMakefile, then you need to callmake checkinstead ofmake test.) cmake(orautomake) 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}
  coverage: /^\s*lines:\s*\d+.\d+\%/
  artifacts:
    name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
    expire_in: 2 days
    reports:
      cobertura: build/coverage.xml
			
		