프로젝트에 Jacoco를 적용해서 테스트 커버리지를 확인해보자. 그리고 나서 git actions와 codecov를 사용하여 PR에 커버리지 코멘트를 달아보자.
1. build.gradle 설정
plugins {
// ...
id 'jacoco' //추가
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
jacoco {
toolVersion = "0.8.8" //추가: 버전 명시
}
dependencies {
//생략
}
tasks.named('test') {
useJUnitPlatform()
finalizedBy jacocoTestReport //추가: test가 수행될 때마다 jacocoTestReport 작업 수행
}
//추가
jacocoTestReport {
dependsOn test // tast 실행 전에 수행될 task
reports { // 어떤 파일을 생성할지/생성하지 않을지
xml.required = true
html.required = true
csv.required = false
// 기본 경로 $buildDir/reports/jacoco/test
// 리포트 타입마다 destination file 옵션으로 경로 변경 가능
// html.destination file("$buildDir/jacocoHtml")
// xml.destination file("$buildDir/jacoco.xml")
}
}
2023.12.26일 enabled가 아닌 required로 변경
테스트 커버리지 기준(선택사항)
jacocoTestCoverageVerification Task를 정의하여 테스트 커버리지 기준을 정할 수 있다.
jacocoTestCoverageVerification {
violationRules {
rule {
element = 'CLASS'
enabled = true
limit {
counter = 'LINE'
value = 'COVEREDRATIO'
minimum = 0.6
}
}
}
}
element
- 어떤 요소에 커버리지 기준을 적용할지 나타냄
- BUNDLE(디폴트), PACKAGE, CLASS, SOURCEFILE, METHOD 중 에서 하나를 선택
enabled
- 해당 rule 활성화 여부, 디폴트 true
limit
- 커버리지 기준 정의
counter
- 커버리지 측정 최소 단위
- INSTRUCTION(디폴트): Java 바이트 코드 명령 수에 대한 커버리지
- BRANCH: 브랜치 코드(조건문등 분기)의 커버리지
- LINE: 빈 줄을 제외한 실제 소스 코드의 라인에 대한 커버리지
- METHOD: 메서드에 대한 커버리지
- CLASS: 클래스에 대한 커버리지
- COMPLEXITY: 복잡도
value
- 커버리지 측정 방법
- TOTALCOUNT: 전체 개수
- MISSDCOUNT: 커버되지 않은 개수
- COVEREDCOUNT: 커버된 개수
- MISSEDRATIO: 커버되지 않은 비율(0~1사이)
- COVEREDRATIO(디폴트): 커버된 비율(0~1사이)
minimum
- value 측정 방법의 최소 기준
2. 테스트 코드 실행
테스트 코드를 실행해보자.
다음과 같이 build 패키지에 jacoco와 관련된 패키지가 생겼다.
리포트가 생성되는 디폴트 경로 build/reports/jacoco 로 가보면 html 파일은 test/html 폴더 하위에, xml 파일은 test 폴더 하위에 생성된 것을 확인할 수 있다.
html 파일을 열어보면 다음과 같은 창이 뜨고, 테스트 커버리지를 확인할 수 있다.
3. 순서 지정
jacocoTestCoverageVerification Task와 jacocoTestReport Task의 순서를 지정하지 않으면 jacocoTestCoverageVerification Task가 jacocoTestReport Task 보다 먼저 실행될 수 있다.
이때 jacocoTestCoverageVerification Task에서 지정해둔 커버리지 기준을 통과하지 못하면 jacocoTestReport Task가 실행되지 않는다. 그렇게 되면 리포트가 새로 생성되지 못해 이전의 리포트를 계속 보게되는 문제가 생길 수 있다.
build.gradle에 다음 Task를 생성하자.
task testCoverage(type: Test) {
group 'verification'
description 'Runs the unit tests with coverage'
dependsOn(':test',
':jacocoTestReport',
':jacocoTestCoverageVerification')
tasks['jacocoTestReport'].mustRunAfter(tasks['test'])
tasks['jacocoTestCoverageVerification'].mustRunAfter(tasks['jacocoTestReport'])
}
터미털에 다음을 입력하자.
./gradlew --console verbose testCoverage
Task가 수행되는 순서를 보면 jacocoTestReport -> jacocoTestCoverageVerification 순서로 Task가 수행된다.
하지만 매번 이렇게 터미널에 입력하는 것은 귀찮긴 하다.
그래서 필자는 test Task를 실행할 때마다 jacocoTestReport Task를 수행하고, jacocoTestReport Task를 실행할 때마다 jacocoTestCoverageVerification Task를 수행하도록 했다.
tasks.named('test') {
//생략
finalizedBy jacocoTestReport
}
jacocoTestReport {
//생략
finalizedBy jacocoTestCoverageVerification
}
4. PR시 테스트 커버리지 코멘트 추가
프로젝트 root 디렉토리에 codecov.yml을 생성하여 추가하자.
codecov:
require_ci_to_pass: yes
comment:
layout: "reach,diff,flags,files,footer"
behavior: default
require_changes: false
branches:
- main
위 링크로 이동해 codecov token을 받아오자. 깃허브 계정으로 로그인이 가능하다.
로그인을 하면 다음과 같이 All my orgs and repos 라는 창이 뜨고, 잠시 기다리면 내 레포지토리가 보인다.
이 중에서 codecov 토큰이 필요한 레포지토리를 선택하자.
다음과 같이 키를 발급해준다.
발급 받은 키를 복사하고, 해당 레포지토리의 Settings > Secrets and variables > Actions에 추가하자.
Step2의 app도 설치하여 Configure에서 사용하고자 하는 레포지토리를 선택해주자.
이제 actions workflow를 생성해주자.
name: Java CI with Gradle
on:
push:
branches:
- 'main'
pull_request:
branches:
- 'main'
jobs:
code-coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
gradle-version: 7.5.1
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
shell: bash
- name: Build with Gradle
run: ./gradlew test
shell: bash
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
with:
file: ./build/reports/jacoco/test/jacocoTestReport.xml
임시로 test 브랜치를 만들어 파일을 하나 생성하고 main으로 PR을 보내보자.
기다리면 Comment가 생성되는 것을 확인할 수 있다. (10분 정도 걸리기도 한다.)
'Spring' 카테고리의 다른 글
[Spring] Webflux + RSocket, React 사용한 전체 채팅 구현 (0) | 2023.06.02 |
---|---|
[Spring] SpringBoot K6 + Grafana 부하 테스트 및 모니터링 (0) | 2023.05.29 |
[Spring] SpringBoot Prometheus, Grafana를 사용한 모니터링(Feat. Docker) (0) | 2023.05.25 |
[Spring] Spring WebFlux 간단한 예제 (0) | 2023.05.25 |
[Spring] @RequestParam으로 Enum 타입 매개변수 받기 (0) | 2023.05.15 |