Cobertura 커버리지 보고서
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
커버리지 분석이 작동하려면 artifacts:reports:coverage_report에 올바른 형식의 Cobertura XML 보고서를 제공해야 합니다. 다른 커버리지 분석 프레임워크는 기본적으로 이 형식을 지원합니다.
커버리지 분석이 작동하려면 artifacts:reports:coverage_report에 올바른 형식의 Cobertura XML 보고서를 제공해야 합니다. 이 형식은 원래 Java용으로 개발되었지만, 다른 언어 및 플랫폼을 위한 대부분의 커버리지 분석 프레임워크에는 이를 지원하는 플러그인이 있습니다:
- simplecov-cobertura (Ruby)
- gocover-cobertura (Go)
- cobertura (Node.js)
다른 커버리지 분석 프레임워크는 기본적으로 이 형식을 지원합니다. 예를 들면:
- Istanbul (JavaScript)
- Coverage.py (Python)
- PHPUnit (PHP)
구성 후, 머지 리퀘스트가 커버리지 보고서를 수집하는 파이프라인을 트리거하면 diff 뷰에 커버리지 정보가 표시됩니다. 여기에는 파이프라인의 모든 단계에 있는 모든 작업의 보고서가 포함됩니다. 각 줄에 대해 커버리지가 표시됩니다:
covered(녹색): 테스트에서 최소 한 번 이상 확인된 줄no test coverage(주황색): 로드되었지만 실행되지 않은 줄- 커버리지 정보 없음: 계측되지 않았거나 로드되지 않은 줄
커버리지 바에 마우스를 올리면 해당 줄이 테스트에서 확인된 횟수 등 추가 정보를 확인할 수 있습니다.
테스트 커버리지 보고서를 업로드해도 다음 항목은 활성화되지 않습니다:
- 머지 리퀘스트 위젯의 테스트 커버리지 결과.
- 코드 커버리지 기록.
이러한 항목은 별도로 구성해야 합니다.
제한 사항#
Cobertura 형식 XML 파일에는 100개의 <source> 노드 제한이 적용됩니다. 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에서//...형식의 다음 경로:<sources> <source>/builds/test-org/test-cs-project/Auth</source> <source>/builds/test-org/test-cs-project/Lib/Utils</source> </sources>
파서는:
sources에서Auth와Lib/Utils를 추출하고 이를 사용하여 프로젝트 루트에 대한class경로를 결정합니다.- 추출된
sources와 클래스 파일 이름을 결합합니다. 예를 들어,filename값이User.cs인class요소가 있는 경우, 파서는 일치하는 첫 번째 후보 경로인Auth/User.cs를 선택합니다. - 각
class요소에 대해 최대 100번 반복하여 추출된 각source경로에 대한 일치 항목을 찾으려고 시도합니다. 파일 트리에서 일치하는 경로를 찾지 못하면 최종 커버리지 보고서에 해당 클래스가 포함되지 않습니다.
자동 클래스 경로 수정은 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.java인class요소:<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">
자동 클래스 경로 수정은 //... 형식의 source 경로에서만 작동합니다.
경로가 이 패턴을 따르지 않으면 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 예시#
GitLab 17.6 이상에서는 JaCoCo 형식을 기본으로 지원합니다. 새 프로젝트에는 기본 JaCoCo 보고서를 사용하세요.
다음 예시는 jacoco2cobertura Docker 이미지를 사용하여 JaCoCo 보고서를 Cobertura 형식으로 변환합니다.
Maven 예시#
test-jdk11 작업은 Maven을 사용하여 JaCoCo XML 아티팩트를 생성합니다. coverage-jdk11 작업은 이를 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:
# `visualize` 단계는 기본적으로 존재하지 않습니다.
# 먼저 정의하거나 `deploy`와 같은 기존 단계를 사용합니다.
stage: visualize
image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.11
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 예시#
test-jdk11 작업은 Gradle을 사용하여 JaCoCo XML 아티팩트를 생성합니다. coverage-jdk11 작업은 이를 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:
# `visualize` 단계는 기본적으로 존재하지 않습니다.
# 먼저 정의하거나 `deploy`와 같은 기존 단계를 사용합니다.
stage: visualize
image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.11
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 예시#
다음 PHP용 .gitlab-ci.yml 예시는 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
PHPUnit을 통한 Codeception도 run을 사용하여 Cobertura 보고서 생성을 지원합니다. 생성된 파일의 경로는 --coverage-cobertura 옵션과 단위 테스트 스위트의 paths 구성에 따라 달라집니다. 적절한 경로에서 Cobertura를 찾을 수 있도록 .gitlab-ci.yml을 구성합니다.
C/C++ 예시#
다음 C/C++ .gitlab-ci.yml 예시는 gcc 또는 g++를 컴파일러로 사용하며, gcovr을 사용하여 Cobertura XML 형식으로 커버리지 출력 파일을 생성합니다.
이 예시는 다음을 가정합니다:
Makefile이 이전 단계의 다른 작업에서build디렉터리의cmake에 의해 생성됩니다. (automake를 사용하여Makefile을 생성하는 경우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 예시#
다음 Go용 .gitlab-ci.yml 예시는 다음을 사용합니다:
go test로 테스트를 실행합니다.gocover-cobertura로 Go의 커버리지 프로파일을 Cobertura XML 형식으로 변환합니다.
이 예시는 Go 모듈이 사용되고 있다고 가정합니다. -covermode count 옵션은 -race 플래그와 함께 작동하지 않습니다. -race 플래그를 사용하면서 코드 커버리지를 생성하려면 -covermode count보다 느린 -covermode atomic으로 전환해야 합니다. 자세한 내용은 이 블로그 게시물을 참조하세요.
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 예시#
다음 Ruby용 .gitlab-ci.yml 예시는 다음을 사용합니다:
rspec으로 테스트를 실행합니다.simplecov와simplecov-cobertura로 커버리지 프로파일을 기록하고 Cobertura XML 형식으로 보고서를 생성합니다.
이 예시는 다음을 가정합니다:
- 종속성 관리를 위해
bundler가 사용됩니다.rspec,simplecov,simplecov-coberturagem이Gemfile에 추가되었습니다. spec_helper.rb파일의SimpleCov.formatters구성에CoberturaFormatter가 추가되었습니다.
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
문제 해결#
테스트 커버리지 시각화가 표시되지 않음#
diff 뷰에 테스트 커버리지 시각화가 표시되지 않으면 커버리지 보고서 자체를 확인하고 다음을 검증할 수 있습니다:
- diff 뷰에서 보고 있는 파일이 커버리지 보고서에 언급되어 있습니다.
- 보고서의
source및filename노드가 리포지터리의 파일과 일치하는 예상 구조를 따릅니다. - 파이프라인이 완료되었습니다. 파이프라인이 수동 작업에서 차단된 경우, 파이프라인은 완료된 것으로 간주되지 않습니다.
- 커버리지 보고서 파일이 제한 사항을 초과하지 않습니다.
보고서 아티팩트는 기본적으로 다운로드할 수 없습니다. 작업 세부 정보 페이지에서 보고서를 다운로드할 수 있게 하려면 커버리지 보고서를 아티팩트 paths에 추가합니다:
artifacts:
paths:
- coverage/cobertura-coverage.xml
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
