Cobertura 커버리지 보고서

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

커버리지 분석이 작동하려면 올바르게 형식화된
Cobertura XML 보고서를
artifacts:reports:coverage_report로 제공해야 합니다.
이 형식은 원래 Java를 위해 개발되었지만, 다른 언어의 대부분의 커버리지 분석 프레임워크는
이를 지원하는 플러그인을 가지고 있습니다. 예:

기타 커버리지 분석 프레임워크는 이 형식을 기본적으로 지원합니다. 예:

구성이 완료되면, 병합 요청이 커버리지 보고서를 수집하는 파이프라인을 트리거하면, 커버리지 정보가
diff 뷰에 표시됩니다. 이는 파이프라인의 모든 단계에서 모든 작업의 보고서를 포함합니다.
각 줄에 대한 커버리지 표시:

  • covered (녹색): 테스트에 의해 최소한 한 번 확인된 줄
  • no test coverage (주황색): 로드되었지만 실행되지 않은 줄
  • 커버리지 정보 없음: 측정되지 않거나 로드되지 않은 줄

커버리지 바 위에 마우스를 올리면, 해당 줄이 테스트에 의해 몇 번 확인되었는지와 같은 추가 정보가 제공됩니다.

테스트 커버리지 보고서를 업로드하는 것은 다음을 활성화하지 않습니다:

이들은 별도로 구성해야 합니다.

제한 사항

Cobertura 형식 XML 파일에 대한 <source> 노드 수의 제한은 100개입니다.
Cobertura 보고서가 100개 노드를 초과할 경우, 병합 요청의 diff 뷰에 불일치가 발생하거나
일치하지 않을 수 있습니다.

단일 Cobertura XML 파일의 크기는 10 MiB를 초과할 수 없습니다.
대형 프로젝트의 경우, Cobertura XML을 더 작은 파일로 분할하십시오.
자세한 내용은 이 이슈를 참조하십시오.
여러 파일을 제출할 경우, 커버리지가 병합 요청에 표시되기까지 몇 분이 걸릴 수 있습니다.

시각화는 파이프라인이 완료된 후에만 표시됩니다.
파이프라인에 차단 수동 작업이 있는 경우,
파이프라인은 수동 작업이 완료될 때까지 기다리며, 완료된 것으로 간주되지 않습니다.
차단 수동 작업이 실행되지 않은 경우, 시각화를 표시할 수 없습니다.

작업이 여러 보고서를 생성하는 경우, 아티팩트 경로에 와일드카드를 사용하십시오

자동 클래스 경로 수정

커버리지 보고서는 class 요소의 filename에 프로젝트 루트에 대한 전체 경로가 포함된 경우에만 변경된 파일과
정확하게 일치합니다. 그러나 일부 커버리지 분석 프레임워크에서는 생성된 Cobertura XML이 filename 경로를
클래스 패키지 디렉토리에 상대적으로 설정합니다.

프로젝트 루트 상대 class 경로에 대해 지능적인 추정을 하려고 Cobertura XML 파서는
전체 경로를 빌드하려고 시도합니다:

  • sources 요소에서 source 경로의 일부를 추출하여 클래스 filename 경로와 결합합니다.
  • 후보 경로가 프로젝트에 존재하는지 확인합니다.
  • 일치하는 첫 번째 후보 경로를 클래스 전체 경로로 사용합니다.

경로 수정 예제

예를 들어, 다음과 같은 C# 프로젝트가 있습니다:

  • 전체 경로는 test-org/test-cs-project입니다.
  • 프로젝트 루트에 상대적인 다음 파일들:

    Auth/User.cs
    Lib/Utils/User.cs
    
  • Cobertura XML의 sources에서, 다음과 같은 경로들(형식 <CI_BUILDS_DIR>/<PROJECT_FULL_PATH>/...):

    <sources>
      <source>/builds/test-org/test-cs-project/Auth</source>
      <source>/builds/test-org/test-cs-project/Lib/Utils</source>
    </sources>
    

파서는:

  • sources에서 AuthLib/Utils를 추출하고, 이를 사용하여 프로젝트 루트에 상대적인 class 경로를 결정합니다.

  • 추출된 sources와 클래스 파일 이름을 결합합니다. 예를 들어, filename 값이 User.csclass 요소가 있는 경우, 파서는 일치하는 첫 번째 후보 경로인 Auth/User.cs를 사용합니다.

  • class 요소에 대해, 추출된 각 source 경로에 대해 최대 100회 반복하여 일치를 찾으려고 시도합니다. 이 한도를 초과하여 파일 트리에서 일치하는 경로를 찾지 못하면, 해당 클래스는 최종 커버리지 보고서에 포함되지 않습니다.

자동 클래스 경로 수정은 다음과 같은 Java 프로젝트에서도 작동합니다:

  • 전체 경로는 test-org/test-java-project입니다.
  • 프로젝트 루트에 상대적인 다음 파일:

    src/main/java/com/gitlab/security_products/tests/App.java
    
  • Cobertura XML의 sources:

    <sources>
      <source>/builds/test-org/test-java-project/src/main/java/</source>
    </sources>
    
  • filename 값이 com/gitlab/security_products/tests/App.javaclass 요소:

    <class name="com.gitlab.security_products.tests.App" filename="com/gitlab/security_products/tests/App.java" line-rate="0.0" branch-rate="0.0" complexity="6.0">
    

참고: 자동 클래스 경로 수정은 <CI_BUILDS_DIR>/<PROJECT_FULL_PATH>/... 형식의 source 경로에서만 작동합니다. 이 패턴을 따르지 않는 경로는 무시됩니다. 파서는 class 요소의 filename이 프로젝트 루트에 상대적인 전체 경로를 포함하고 있다고 가정합니다.

예제 테스트 커버리지 구성

이 섹션에서는 다양한 프로그래밍 언어에 대한 테스트 커버리지 구성 예제를 제공합니다. 또한 coverage-report 데모 프로젝트에서 작동하는 예제를 볼 수 있습니다.

JavaScript 예제

다음 .gitlab-ci.yml 예제는 Mocha JavaScript 테스트와 nyc 커버리지 도구를 사용하여 커버리지 아티팩트를 생성합니다:

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

Java 및 Kotlin 예제

Maven 및 Gradle 예제는 JaCoCo 보고서를 Cobertura 형식으로 변환합니다. 또는, 이슈 227345네이티브 JaCoCo 보고서 지원을 가능하게 하기 위한 작업을 추적합니다.

Maven 예제

다음 .gitlab-ci.yml 예제는 Java 또는 Kotlin을 위해 Maven을 사용하여 프로젝트를 빌드하고 JaCoCo 커버리지 도구를 사용하여 커버리지 아티팩트를 생성합니다.

자신의 이미지를 빌드하려면 Docker 이미지 구성 및 스크립트를 확인할 수 있습니다.

GitLab은 아티팩트가 Cobertura 형식일 것으로 기대하므로, 업로드하기 전에 몇 가지 스크립트를 실행해야 합니다. test-jdk11 작업은 코드를 테스트하고 XML 아티팩트를 생성합니다. coverage-jdk-11 작업은 아티팩트를 Cobertura 보고서로 변환합니다:

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:
  # test-jdk11의 단계보다 나중에 있어야 합니다.
  # `visualize` 단계는 기본적으로 존재하지 않습니다.
  # 먼저 정의하거나 `deploy`와 같은 기존 단계를 선택하세요.
  stage: visualize
  image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.9
  script:
    # jacoco에서 cobertura로 보고서를 변환하고 상대 프로젝트 경로를 사용
    - 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 예제

다음 .gitlab-ci.yml 예제는 Java 또는 Kotlin을 위해 Gradle을 사용하여 프로젝트를 빌드하고 JaCoCo 커버리지 도구를 사용하여 커버리지 아티팩트를 생성합니다.

자신의 이미지를 빌드하려면 Docker 이미지 구성 및 스크립트를 확인할 수 있습니다.

GitLab은 아티팩트가 Cobertura 형식일 것으로 기대하므로, 업로드하기 전에 몇 가지 스크립트를 실행해야 합니다. test-jdk11 작업은 코드를 테스트하고 XML 아티팩트를 생성합니다. coverage-jdk-11 작업은 아티팩트를 Cobertura 보고서로 변환합니다:

test-jdk11:
  stage: test
  image: gradle:6.6.1-jdk11
  script:
    - 'gradle test jacocoTestReport' # jacoco는 xml 보고서를 생성하도록 구성되어야 합니다.
  artifacts:
    paths:
      - build/jacoco/jacoco.xml

coverage-jdk11:
  # test-jdk11의 단계보다 나중에 있어야 합니다.
  # `visualize` 단계는 기본적으로 존재하지 않습니다.
  # 먼저 정의하거나 `deploy`와 같은 기존 단계를 선택하세요.
  stage: visualize
  image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
  script:
    # jacoco에서 cobertura로 보고서를 변환하고 상대 프로젝트 경로를 사용
    - 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 예제

다음 .gitlab-ci.yml 예제는 pytest-cov를 사용하여 테스트 커버리지 데이터를 수집합니다:

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 예제

다음 .gitlab-ci.yml PHP 예제는 PHPUnit를 사용하여 테스트 커버리지 데이터를 수집하고 리포트를 생성합니다.

최소한의 phpunit.xml 파일을 사용하면 (이 예제 저장소를 참조할 수 있습니다), 테스트를 실행하고 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은 PHPUnit를 통해 Cobertura 리포트를 생성하는 것도 지원하며 run 명령을 사용합니다. 생성된 파일의 경로는 --coverage-cobertura 옵션과 unit test suitepaths 설정에 따라 다릅니다. .gitlab-ci.yml을 구성하여 적절한 경로에서 Cobertura를 찾을 수 있도록 합니다.

C/C++ 예제

다음 .gitlab-ci.yml C/C++ 예제는 gcc 또는 g++를 컴파일러로 사용하며 gcovr을 사용하여 Cobertura XML 형식의 커버리지 출력 파일을 생성합니다.

이 예제는 다음을 가정합니다:

  • Makefilebuild 디렉토리에서 cmake에 의해 생성됩니다, 이전 단계의 다른 작업에서. (Makefile을 생성하기 위해 automake를 사용하는 경우, make test 대신 make check를 호출해야 합니다.)
  • cmake(또는 automake)가 컴파일러 옵션 --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 예제

다음 .gitlab-ci.yml Go 예제는 다음을 사용합니다:

  • go test는 테스트를 실행합니다.
  • gocover-cobertura는 Go의 신뢰도 프로파일을 Cobertura XML 형식으로 변환합니다.

이 예제는 Go 모듈을 사용하는 것으로 가정합니다. -covermode count 옵션은 -race 플래그와 함께 작동하지 않습니다. -race 플래그를 사용하면서 코드 커버리지를 생성하려면 -covermode atomic으로 전환해야 하며, 이는 -covermode count보다 느립니다. 자세한 내용은 이 블로그 게시물을 참조하세요.

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 예제

다음 .gitlab-ci.yml Ruby 예제는 다음을 사용합니다:

  • rspec는 테스트를 실행합니다.
  • simplecovsimplecov-cobertura는 커버리지 프로파일을 기록하고 Cobertura XML 형식으로 보고서를 생성합니다.

이 예제는 다음을 가정합니다:

  • bundler가 종속성 관리를 위해 사용됩니다. rspec, simplecovsimplecov-cobertura 젬이 Gemfile에 추가되었습니다.
  • CoberturaFormatterspec_helper.rb 파일의 SimpleCov.formatters 구성에 추가되었습니다.
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

문제 해결

테스트 커버리지 시각화가 표시되지 않음

테스트 커버리지 시각화가 차이 뷰에서 표시되지 않는 경우, 커버리지 보고서를 확인하고 다음을 검증할 수 있습니다:

  • 차이 뷰에서 보고 있는 파일이 커버리지 보고서에 언급되어 있습니다.
  • 보고서의 sourcefilename 노드가 레포지토리의 파일과 일치하는 예상 구조를 따릅니다.
  • 파이프라인이 완료되었습니다. 파이프라인이 수동 작업에서 차단된 경우, 파이프라인은 완료되지 않은 것으로 간주됩니다.
  • 커버리지 보고서 파일이 제한을 초과하지 않습니다.

리포트 아티팩트는 기본적으로 다운로드할 수 없습니다. 작업 세부 정보 페이지에서 보고서를 다운로드할 수 있도록 하려면 커버리지 보고서를 아티팩트 paths에 추가하세요:

artifacts:
  paths:
    - coverage/cobertura-coverage.xml
  reports:
    coverage_report:
      coverage_format: cobertura
      path: coverage/cobertura-coverage.xml