1. 배경
테스트 코드의 품질을 관리하기 위해서는 단순히 테스트가 "통과"하는지만 보는 것이 아니라, 얼마나 많은 코드가 테스트되었는가(커버리지) 도 중요합니다.
특히 CI 환경(GitHub Actions, Jenkins 등)에서 커버리지를 자동 측정하고 PR 단위로 확인할 수 있다면, 팀 전체적으로 코드 품질을 꾸준히 유지하는데 큰 도움이 됩니다.
이번에 저는 Gradle + JaCoCo + Codecov 조합으로 프로젝트에 커버리지 측정을 적용했습니다.
2. JaCoCo란?
JaCoCo(Java Code Coverage)는 자바 프로젝트에서 테스트 커버리지를 측정하기 위한 도구입니다.
JaCoCo에서 기본적으로 제공하는 커버리지 종류는:
- 라인(Line) 커버리지: 실제 실행된 코드 라인의 비율
- 브랜치(Branch) 커버리지: 조건문(if, switch 등)의 분기 실행 비율
- 클래스/메서드 커버리지: 테스트된 클래스와 메서드 비율
- 사이클로매틱 복잡도(Complexity)
일반적으로 라인 커버리지를 기준으로 최소 품질 게이트를 두고, 브랜치 커버리지는 보조적으로 관리합니다. (브랜치 커버리지는 조건문이 많으면 달성하기 어렵습니다.)
3. Gradle 프로젝트에 JaCoCo 적용
✅ 환경
- Gradle 8.14.3
- build.gradle (Groovy DSL)
- 목표:
- 라인 커버리지 80% 이상
- 브랜치 커버리지 60% 이상
✅ 설정 예시
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.4'
id 'io.spring.dependency-management' version '1.1.7'
id 'jacoco'
}
group = 'com.project'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
jacoco {
toolVersion = "0.8.12"
}
test {
useJUnitPlatform()
finalizedBy jacocoTestReport
systemProperty "spring.profiles.active", "test"
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
jacocoTestReport {
dependsOn test
reports {
xml.required = true
html.required = true
csv.required = false
}
// global 패키지 제외 (리포트 생성 단계)
afterEvaluate {
classDirectories.setFrom(
files(classDirectories.files.collect {
fileTree(dir: it, exclude: [
'com/project/questday/global/**'
])
})
)
}
}
jacocoTestCoverageVerification {
violationRules {
rule {
// global 패키지 제외 (검증 단계)
excludes = [
'com/project/questday/global/**'
]
// 라인 커버리지
limit {
counter = 'LINE'
value = 'COVEREDRATIO'
minimum = 0.60
}
// 브랜치 커버리지
limit {
counter = 'BRANCH'
value = 'COVEREDRATIO'
minimum = 0.00
}
}
}
}
// check task에 커버리지 검증 연결
check.dependsOn jacocoTestCoverageVerification
repositories {
mavenCentral()
}
dependencies {
// Spring Boot Core
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
// Logging
implementation 'org.springframework.boot:spring-boot-starter-logging'
// Devtools
developmentOnly 'org.springframework.boot:spring-boot-devtools'
// MySQL
runtimeOnly 'com.mysql:mysql-connector-j'
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// H2 Database for testing
testImplementation 'com.h2database:h2'
}
tasks.named('test') {
useJUnitPlatform()
}
- jacocoTestReport: HTML, XML 리포트를 생성 (특히 Codecov 업로드용 XML 필요)
- jacocoTestCoverageVerification: 빌드 시 커버리지 기준 미달이면 실패 처리
4. GitHub Actions + Codecov 연동
JaCoCo는 로컬에서 HTML 리포트를 확인할 수 있지만, CI에서 PR 단위로 확인하려면 Codecov 같은 외부 서비스가 필요합니다.
✅ GitHub Actions 예시
name: CODECOV_CI
on:
pull_request:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# gradlew 실행 권한 부여
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
# JDK 설정
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
# Gradle 빌드 및 테스트 실행 (테스트 프로파일 적용)
- name: Build and run tests with Gradle
run: ./gradlew clean build jacocoTestReport
env:
SPRING_PROFILES_ACTIVE: test
# Codecov 업로드
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: build/reports/jacoco/test/jacocoTestReport.xml
flags: unittests
fail_ci_if_error: true
- 테스트 실행 후 jacocoTestReport.xml을 Codecov에 업로드
- PR에 Codecov 봇이 자동으로 커버리지 리포트를 댓글로 남김
5. 결과 확인
🔎 로컬에서 확인
- build/reports/jacoco/test/html/index.html → 패키지/클래스 단위 라인/브랜치 커버리지 확인 가능


🔎 CI에서 확인
- Codecov PR 코멘트 → PR 단위로 커버리지 변화 확인
- 기준 미달 시 ./gradlew check 단계에서 빌드 실패

6. 적용 효과
- 품질 게이트 적용: 커버리지가 기준 미달이면 빌드 실패 → 테스트 코드 부족 구간 빠르게 확인 가능
- PR 리뷰 개선: 코드 변경이 테스트 커버리지에 미치는 영향 확인 가능
- 팀 차원의 코드 품질 관리: 장기적으로 테스트 코드 작성 습관 강화
- 시각화: JaCoCo HTML + Codecov 대시보드로 직관적으로 파악
7. 마무리
JaCoCo와 Codecov를 조합하면, 단순한 테스트 통과 여부를 넘어서 "얼마나 잘 테스트되었는가" 를 CI 단계에서 바로 확인할 수 있습니다.
특히 오픈소스 프로젝트나 팀 협업 환경에서 큰 장점이 있으며, PR 기반의 품질 게이트를 통해 테스트 부족 영역을 빠르게 식별할 수 있습니다.
'프로젝트' 카테고리의 다른 글
| 데이터 페이징(Pagination) 기법 (0) | 2025.09.19 |
|---|---|
| 테스트 커버리지 점진적으로 높이기 (1) | 2025.08.25 |
| 로깅(Logging)과 Logback 정리 (3) | 2025.08.09 |
| Spring Boot에서 요청 로그에 userId와 requestId 추가하기 (MDC + Logback) (3) | 2025.08.07 |
| EC2에서 RDS 접속하기 (0) | 2025.05.15 |