♻️ Jacoco란?
Jacoco는 Java Code Coverage의 약자로 자바 테스트 코드를 실행한 결과를 바탕으로 커버리지를 측정하는 오픈소스 라이브러리 입니다.
Jacoco를 사용하여 테스트 코드 커버리지 결과를 눈으로 보기 좋도록 html이나 xml, csv 같은 리포트로 생성합니다.
그리고 테스트 결과가 내가 설정한 커버리지를 기준을 만족하는지 테스트 하는 기능도 제공합니다.
🐘 Gradle에서 Jacoco를 통하여 테스트 커버리지 확인하기
적용하기 전에 테스트한 환경은 다음과 같습니다.
Spring boot 2.7.1
Java 17
Gradle
- build.gradle에 jacoco 플러그인을 추가합니다.
plugins { ... ... id 'jacoco' ... }
- jacoco 버전을 지정해줍니다.
- toolVersion
- reportsDir
jacoco { toolVersion = "0.8.8" // reportsDir = file("$buildDir/customJacocoReportDir") }
jacoco 버전을 명시하는 명령입니다.
생성한 테스트 결과를 어디에 저장할지 지정하는 명령입니다.
- 테스트 실행시 결과 문서를 생성하기 위해 다음 설정을 추가합니다.
- useJUnitPlatform()
- finalizedBy
test { useJUnitPlatform() finalizedBy jacocoTestReport }
Junit을 사용하여 테스트를 하기 위해 추가합니다.
task 이후 실행시킬 task를 설정해줍니다. 단, 해당 task의 성공/실패 여부와 상관없이 실행시킵니다.
예를들어 finalizedBy jacocoTestCoverageVerification 라고 할 경우 test 실행 후 jacocoTestCoverageVerification를 실행시킵니다.
- jacoco 테스트 결과 문서를 생성하기 위해 다음과 같은 설정을 추가합니다.
- jacocoTestReport {…}
- dependsOn
- reports {…}
- xml.required
jacocoTestReport { dependsOn test reports { xml.required = true } finalizedBy 'jacocoTestCoverageVerification' }
바이너리 커버리지 결과를 사람이 읽기 좋은 형태의 리포트로 저장합니다.
html 파일로 생성해 사람이 쉽게 눈으로 확인할 수도 있고 SonarQube와 연동하기 위해 xml, csv 같은 형태로도 리포트를 생성할 수 있습니다.
따로 jacoco에 설정을 하지 않았다면
$buildDir/reports/jacoco/test/
경로에 생성됩니다.task가 실행되기 전에 수행 될 task를 설정해줍니다. 이전 task가 성공해야 자신이 실행됩니다.
예를들어 dependsOn ‘test’라고 지정하면 test라는 task를 먼저 실행하고 test가 성공하면 해당 task가 실행됩니다.
특정 형태의 리포트(html, xml, csv)를 생성하거나 생성하지 않는 것을 알려줄 때 사용하는 구문입니다.
테스트 실행 결과를 xml 파일로 생성할지 선택하는 명령입니다.
true일 경우 jacocoTestReport에 명시된 경로에 xml 파일이 생성되며(기본 값
$buildDir/reports/jacoco/test/
) false일 경우 생성되지 않습니다.xml.destination file
옵션으로 각각의 파일마다 report 저장 경로를 변경할 수 있습니다. - 테스트를 실행했을 때 지정한 값을 기준으로 커버리지를 체크하는 설정을 추가합니다.
- jacocoTestCoverageVerification {...}
- violationRules {…}
- rule {…}
- element
- BUNDLE(default) → 패키지 번들
- PACKAGE → 패키지
- CLASS → 클래스
- SOURCEFILE → 소스파일
- METHOD → 메서드
- enabled
- limit {…}
- counter
- LINE → 빈 줄을 제외한 실제 코드의 라인 수
- BRANCH → 조건문 등의 분기 수
- CLASS → 클래스 수
- METHOD → 메서드 수
- INSTRUCTION (default) → Java 바이트 코드 명령 수
- COMPLEXITY → 복잡도
- value
- TOTALCOUNT → 전체 개수
- MISSDCOUNT → 커버되지 않은 카운트
- COVEREDCOUNT → 커버된 개수
- MISSEDRATIO → 커버되지 않은 비율, 0부터 1 사이의 숫자로 1이 100%입니다.
- COVEREDRATIO (default) → 커버된 비율, 0부터 1이사이의 숫자로 1이 100%입니다.
- minimum
jacocoTestCoverageVerification { violationRules { rule { element = 'CLASS' enabled = true limit { counter = 'LINE' value = 'COVEREDRATIO' minimum = 0.60 } limit { counter = 'METHOD' value = 'COVEREDRATIO' minimum = 0.60 } } } }
해당 본문에서 설정한 커버리지 기준을 만족하는 코드를 짰는지 확인할 때 사용하는 task 입니다.
커버리지 기준을 설정하는 여러 룰들을 정의할 때 사용합니다.
커버리지 기준을 설정하는 룰을 정의할 때 사용합니다.
커버리지 체크 기준을 설정합니다. element는 다음 중에 하나를 선택할 수 있습니다.
해당하는 룰을 크고 켤때 사용합니다. true면 해당 룰을 적용하고 false면 적용하지 않습니다.
커버리지 기준을 정의할 때 사용합니다.
예를들어, 메서드는 커버리지를 최소한 60%를 만족해야 한다, 코드의 라인 수는 최대 200라인으로 제한한다와 같은 설정들이 들어가게 됩니다.
측정의 주체가 되는 것이 counter가 됩니다.
어떤 것을 측정할 지 지정할 때 사용됩니다.
value에서 사용된 측정 방법에 따라 최소 지표를 정하는 부분입니다.
예를들어, 테스트 커버리지 60% 이상을 원한다면 COVERDRATIO를 value에서 지정한 후 minimum 값으로 0.6을 주면 됩니다.
이제 코드를 실행해보면 jacoco가 잘 동작하는 것을 확인할 수 있습니다.
✅ Github actions를 이용하여 테스트 커버리지 체크 결과 확인하기
이제 CI 환경에서 jacoco를 사용하기 위해 yaml 파일에 다음 설정을 추가합니다.
- name: Add coverage to PR id: jacoco uses: madrapps/jacoco-report@v1.2 with: paths: ${{ github.workspace }}/build/reports/jacoco/test/jacocoTestReport.xml token: ${{ secrets.GITHUB_TOKEN }} title: "테스트 커버리지 측정" min-coverage-overall: 60 min-coverage-changed-files: 60
- madrapps/jacoco-reposrt@v1.2
- jacoco 결과를 pull request에 추가해주는 라이브러리를 가져옵니다.
- paths
- jacoco 테스트 결과 파일이 위치한 경로를 지정합니다.
- token
- Pull Request에 코멘트를 추가하기 위해 사용하는 Github 개인 토큰을 의미합니다.
- title
- 추가된 내용에 대한 제목을 지정합니다.
- min-coverage-overall
- 전체 파일에 대한 최소 커버리지를 지정할 때 사용합니다.
- min-coverage-changed-files
- 수정된 파일에 대한 최소 커버리지를 지정할 때 사용합니다.
해당 내용을 추가하고 풀리퀘스트 요청을 날려보면 다음과 같이 코드 커버리지를 잘 측정하는 것을 확인할 수 있습니다.

❗ 적용중 발생했던 문제
- 인텔리제이로 한 파일만 테스트 할 경우 Jacoco에서 터뜨리는 현상
전체 테스트를 하지 않는 경우 다른 자바코드에 대한 테스트가 이루어지지 않아 자코코에서 커버리지를 충족하지 못하고 터뜨리는 문제였습니다.
만약 커버리지를 충족한다면 전체 테스트를 해보면 정상적으로 되는 것을 확인할 수 있습니다.
🧐 참고자료
jacoco-report
Madrapps • Updated Aug 17, 2022