Java code coverage
의 약자로, Junit 테스트의 결과를 바탕으로 코드 커버리지 결과를 리포트 해주는 툴이다. 테스트 코드는 개발 시간을 굉장히 단축시켜주는 강력한 도구입니다. 테스트 코드 작성을 꼼꼼히 해야하는데, 이를 강제해주는 좋은 라이브러리입니다.
테스트 코드가 현재 프로덕션코드의 얼마만큼 작성되었는지 퍼센테이지로 확인하도록 해주는 라이브러리 입니다. 만약 커버리지가 100퍼센트라면, 모든 프로덕션 코드에 대해서 테스트 코드가 작성되어 있는 상태라고 할 수 있을 것 입니다.
심지어 JaCoCo는 이렇게 커버리지 결과를 알려줄뿐만 아니라, 해당 커버리지가 사용자가 설정한 퍼센테이지에 미치지 못하면 build자체가 되지않게 설정하여, 테스트코드 작성을 강제합니다.
코드 커버리지
테스트 케이스가 얼마나 충분한가를 나타내는 지표로, 테스트를 진행하였을 때 코드 자체가 얼마나 실행되었는지에 대한 수치이다.
uild.gradle에 JaCoCo를 설정해 줍니다. plugins부분에 아래와 같은 부분을 추가해주면, Gradle이 알아서 해당 의존성을 추가해줍니다.
plugins {
id 'jacoco'
}
JaCoCo의 의존성을 추가하고 나면 별도의 설정이 필요한데 커버리지의 퍼센테이지를 설정하고, 해당 리포트를 어떤 형식으로 저장할 지를 설정해주어야 합니다.
jacoco {
// JaCoCo 버전
toolVersion = '0.8.7'
// 테스트결과 리포트를 저장할 경로 변경하는 방법
// default는 "$/jacoco"
// customJacocoReportDir이라는 디렉토리를 build 디렉토리 내에 생성하고 결과 리포트를 저장합니다.
reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir')
}
test {
// finalizedBy : 이(test) 작업에 대해 주어진 종료자 작업을 추가
finalizedBy jacocoTestReport // test 작업이 끝나고 jacocoTestReport를 실행
}
jacocoTestReport {
// dependsOn : 이 작업에 지정된 종속성을 추가
dependsOn test // jacocoTestReport 에 test라는 종속성을 추가
}
jacocoTestReport {
reports {
// XML 형식의 리포트가 필요하지 않을 경우 false
xml.required = false
// CSV 형식의 리포트가 필요하지 않을 경우 false
csv.required = false
// HTML 형식의 리포트를 생성하고 결과를 jacocoHtml 디렉토리에 저장합니다.
// 여기서 layout.buildDirectory.dir 함수를 사용하여 디렉토리 경로를 지정합니다.
html.outputLocation = layout.buildDirectory.dir('jacocoHtml')
}
}
// 코드 커버리지 검증 규칙을 설정
jacocoTestCoverageVerification {
violationRules {
// 전체 코드 커버리지의 최소 기준
rule {
limit {
// 전체 커버리지가 최소 50% 이상
minimum = 0
}
}
// 클래스 수준의 규칙을 설정
rule {
enabled = true
element = 'CLASS'
// 여기에 있는 패키지만 메서드 커버리지 최소 기준을 설정
// 여기에 없는 패키지는 제외
includes = ['com.example.shopping.service.*']
limit {
counter = 'METHOD'
value = 'COVEREDRATIO'
minimum = 0.5
}
}
}
}
이렇게 하면 JaCoCo가 추가되는데, 오른쪽에 있는 gradle탭을 눌러 Tasks > Verification에 들어가면 아래와 같은 jcocoTestReport와 jacocoTestCoverageVerification 명령이 생긴 것을 확인 할 수 있습니다.
여기서 테스트를 해서 실패를 하고 설정한 기댓값에 미치지 못하면 jacocoTestCoverageVerification 명령을 실행시키면, 에러가 뜨며 해당 명령이 정상적으로 실행되지 않았다고 나올 것 입니다.
에러를 읽어보면, 우리의 테스트코드는 현재 0.33의 커버리지를 갖고있는데, 커버리지 기댓값은 0.90이라고 나와있습니다.
앞서 말했던대로, JaCoCo는 우리가 설정해둔 커버리지 값에 테스트 코드가 미치지 못하면 빌드 자체를 에러를 띄웁니다.
그럼 아까 build.gradle 파일에서 jcocoTestReport에 설정해준 경로,
html.destination file("jacoco/jacocoHtml")
에 생성된 index.html 파일을 열어 자세한 정보를 알아보겠습니다.
index.html 파일을 원하는 브라우저로 열면, 커버리지 퍼센트를 확인 할 수 있습니다. (인텔리제이의 경우 오른쪽 위에 뜨는 팝업에서 브라우저를 누르면 바로 열 수 있습니다.)
혹여 테스트가 불가능 하거나, 위 JacocoApplication 파일처럼 테스트가 필요하지 않은 부분을 커버리지에서 제외해야 할 경우가 있으니, 이를 커버리지에 포함 시키지 않는 방법도 알아보도록 하겠습니다.
@Generated
@SpringBootApplication
public class JacocoApplication {
public static void main(String[] args) {
SpringApplication.run(JacocoApplication.class, args);
}
}
Lombok 라이브러리의 Generated 어노테이션을 붙이면, 해당 클래스를 커버리지에서 제외합니다. 메서드 위에 붙여도 동일하게 작동합니다.