Cobertura Coverage Reports
커버리지 분석이 작동하려면 올바르게 포맷된 Cobertura XML 보고서를 artifacts:reports:coverage_report
에 제공해야 합니다. 이 형식은 원래 Java용으로 개발되었지만, 다른 언어에 대한 대부분의 커버리지 분석 프레임워크에서 이를 지원하기 위한 플러그인이 있습니다. 예를 들어:
- simplecov-cobertura (Ruby)
- gocover-cobertura (Go)
다른 커버리지 분석 프레임워크는 예를 들어 이 형식을 기본적으로 지원합니다:
- Istanbul (JavaScript)
- Coverage.py (Python)
- PHPUnit (PHP)
구성한 후에 만일 병합 요청이 커버리지 보고서를 수집하는 파이프라인을 트리거하면, 커버리지 정보가 차이 보기에 표시됩니다. 이는 파이프라인의 어떤 스테이지의 어떤 작업에서도 보고서가 될 수 있습니다. 커버리지는 각 줄에 대해 다음과 같이 표시됩니다:
-
covered
(녹색): 테스트에 의해 적어도 한 번 확인된 줄 -
no test coverage
(주황색): 로드된 상태이지만 실행되지 않은 줄 - 커버리지 정보 없음: 계기가 없거나 로드되지 않은 줄
커버리지 막대 위로 마우스를 가져가면 줄이 테스트에서 확인된 횟수와 같은 추가 정보가 표시됩니다.
테스트 커버리지 보고서를 업로드해도 다음과 같은 기능을 활성화시키지 않습니다:
이들을 따로 구성해야 합니다.
한계
Cobertura 형식 XML 파일에는 100개의 <source>
노드 제한이 적용됩니다. Cobertura 보고서가 100개의 노드를 초과하면 병합 요청 차이 보기에서 불일치 또는 일치하지 않을 수 있습니다.
하나의 Cobertura XML 파일은 최대 10 MiB여야 합니다. 대규모 프로젝트의 경우, Cobertura XML을 더 작은 파일로 분할하세요. 자세한 내용은 이 문제를 참조하세요. 많은 파일을 제출하는 경우, 커버리지가 병합 요청에 표시되기까지 몇 분이 걸릴 수 있습니다.
시각화는 파이프라인이 완료된 후에만 표시됩니다. 파이프라인에 블로킹 수동 작업이 있는 경우, 파이프라인은 계속 진행되기 전에 수동 작업을 기다리고 완료된 것으로 간주되지 않습니다. 블로킹 수동 작업이 실행되지 않으면 시각화가 표시되지 않습니다.
작업이 여러 보고서를 생성하는 경우, 아티팩트 경로에 와일드카드 사용
자동 클래스 경로 보정
커버리지 보고서는 class
요소의 filename
이 프로젝트 루트에 대한 전체 경로를 포함하는 경우에만 변경된 파일과 일치합니다. 그러나 일부 커버리지 분석 프레임워크에서 생성된 Cobertura XML은 filename
경로가 클래스 패키지 디렉토리에 상대적인 경우가 있습니다.
프로젝트 루트에 대한 지능적인 추측을 위해, Cobertura XML 파서는 다음과 같이 전체 경로를 구축하기 위해 노력합니다:
-
sources
요소에서 추출된 일부sources
경로를 가져와 클래스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
에서 추출된Auth
및Lib/Utils
를 가져와 프로젝트 루트에 대한 클래스filename
경로를 결정할 때 사용합니다. - 이러한 추출된
sources
와 클래스 파일 이름을 결합합니다. 예를 들어,filename
값이User.cs
인class
요소가 있는 경우, 파서는 파일 트리에서 일치하는 경로를 첫 번째로 사용합니다. 결과적으로Auth/User.cs
가 됩니다. - 각
class
요소에 대해 파일 트리에서 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>
-
class
요소의filename
값이com/gitlab/security_products/tests/App.java
인 경우:<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
를 포함할 때만 <CI_BUILDS_DIR>/<PROJECT_FULL_PATH>/...
형식임을 가정합니다. 이 형식에 맞지 않는 경우 source
는 무시됩니다. 파서는 filename
이 class
요소의 전체 경로를 프로젝트 루트에 대한 상대적인 경로를 포함한다고 가정합니다.
테스트 커버리지 구성 예
이 섹션에서는 다양한 프로그래밍 언어에 대한 테스트 커버리지 구성 예를 제공합니다. 또한 실제 작동하는 예제는 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에서 native 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의 stage보다 나중에 실행되어야 합니다.
# `visualize` stage는 기본적으로 존재하지 않습니다.
# 먼저 정의하거나 `배포`와 같은 기존 stage를 선택하세요.
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 must be configured to create an xml report
artifacts:
paths:
- build/jacoco/jacoco.xml
coverage-jdk11:
# test-jdk11의 stage보다 나중에 실행되어야 합니다.
# `visualize` stage는 기본적으로 존재하지 않습니다.
# 먼저 정의하거나 `배포`와 같은 기존 stage를 선택하세요.
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
파일과 함께(참조 가능)
this example repository를 이용하여 테스트를 실행하고
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을 통해 run
을 사용하여
Cobertura 보고서를 생성하는 것을 지원합니다.
생성된 파일에 대한 경로는 --coverage-cobertura
옵션 및 unit test suite에 대한 paths
구성에 따라 달라집니다.
GitLab에서 적절한 경로에 Cobertura를 찾도록 .gitlab-ci.yml
을 구성하세요.
C/C++ 예시
다음 .gitlab-ci.yml
예시는 gcc
또는 g++
컴파일러를 사용하여 gcovr
를 사용하여 Cobertura XML 형식으로 커버리지 출력 파일을 생성하는 C/C++ 예시입니다.
이 예시는 다음을 가정합니다:
-
Makefile
이 이전 단계의 다른 작업에서cmake
에 의해build
디렉토리에 생성되었다는 것 (automake
를 사용하여Makefile
을 생성하는 경우make test
대신make check
를 호출해야 함) -
cmake
(또는automake
)가 컴파일러 옵션--coverage
를 설정했다는 것
테스트 실행:
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
를 사용합니다. - Go의 커버리지 프로필을 Cobertura XML 형식으로 변환하기 위해
gocover-cobertura
를 사용합니다.
이 예시는 Go modules가 사용되고 있다고 가정합니다. -covermode count
옵션은 -race
플래그와 함께 작동하지 않습니다.
-race
플래그를 사용하면서 코드 커버리지를 생성하려면, 느리지만 -covermode count
보다 느린 -covermode atomic
로 전환해야 합니다. 자세한 내용은 이 블로그 글을 참조하세요.
테스트 실행:
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
를 사용합니다. - 커버리지 프로필을 기록하고 Cobertura XML 형식으로 보고서를 작성하기 위해
simplecov
와simplecov-cobertura
를 사용합니다.
이 예시는 다음을 가정합니다:
- 의존성 관리에
bundler
가 사용되고 있다는 것.rspec
,simplecov
,simplecov-cobertura
젬이Gemfile
에 추가되었다는 것. -
CoberturaFormatter
가SimpleCov.formatters
구성에spec_helper.rb
파일에 추가되었다는 것.
테스트 실행:
stage: test
image: ruby:3.1
script:
- bundle install
- bundle exec rspec
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/coverage.xml
문제 해결
테스트 커버리지 시각화가 표시되지 않음
테스트 커버리지 시각화가 차이점 뷰에 표시되지 않는 경우, 커버리지 보고서를 확인하여 다음을 검증할 수 있습니다:
- 차이점 뷰에서 보고 있는 파일이 커버리지 보고서에 언급되어 있는지 확인합니다.
- 보고서의
source
및filename
노드가 저장소의 파일과 일치하도록 예상된 구조를 따르는지 확인합니다. - 파이프라인이 완료되었는지 확인합니다. 파이프라인이 수동 작업에 블록된 경우, 파이프라인은 완료된 것으로 간주되지 않습니다.
- 커버리지 보고서 파일이 제한 사항을 초과하지 않았는지 확인합니다.
보고서 아티팩트는 기본적으로 다운로드할 수 없습니다. 보고서가 작업 세부 정보 페이지에서 다운로드 가능하도록 하려면 커버리지 보고서를 아티팩트 paths
에 추가하세요:
artifacts:
paths:
- coverage/cobertura-coverage.xml
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml