본문 바로가기
프로젝트

[Project] Gradle Build 시 JaCoCo 연동하기

by jaee_ 2021. 12. 5.
!!! 구글링을 하기 전에 공식문서를 보고 먼저 적용해보기 🕵🏻‍♂️

https://docs.gradle.org/current/userguide/jacoco_plugin.html#sec:configuring_the_jacoco_plugin

https://www.eclemma.org/jacoco/trunk/index.html

 

The JaCoCo Plugin

To get started, apply the JaCoCo plugin to the project you want to calculate code coverage for. Example 1. Applying the JaCoCo plugin build.gradle plugins { id 'jacoco' } build.gradle.kts If the Java plugin is also applied to your project, a new task named

docs.gradle.org

 

 

JaCoCo - Java Code Coverage Library

JaCoCo - Java Code Coverage Library JaCoCo is a free Java code coverage library distributed under the Eclipse Public License. Check http://www.jacoco.org/jacoco for updates and feedback. This is the distribution of version 0.8.8.202111170531 created on 202

www.eclemma.org


프로젝트에 JaCoCo 적용시키기

Code Coverage란 무엇일까요? 위키백과에는 다음과 같이 정의되어 있습니다.

코드 커버리지(Code Coverage)는 소프트웨어의 테스트를 논할 때 얼마나 테스트가 충분한가를 나타내는 지표중 하나다. 말 그대로 코드가 얼마나 커버되었는가이다. 소프트웨어 테스트를 진행했을 때 코드 자체가 얼마나 실행되었냐는 것이다.

코드의 구조를 이루는 것은 크게 구문(Statement), 조건(Condition), 결정(Decision)이다. 이러한 구조를 얼마나 커버했느냐에 따라 코드커버리지의 측정기준은 나뉘게 된다.

JaCoCo는 Java Code Coverage의 약자이며, 자바 코드에 대한 코드 커버리지 측정을 제공하는 라이브러리입니다. 저는 현재 프로젝트에 JaCoCo를 적용시켜 테스트의 성공률이 50% 가 넘지 않으면 Build에 실패하도록 적용하려 합니다.

 

자 이제 공식문서를 따라서 적용시켜보도록 하겠습니다.

 

프로젝트 환경 : Junit5 / Gradle 7.2 버전

 

1. JaCoCo 플러그인을 적용

plugins {
    id 'jacoco'
}

위와 같이 플러그인을 적용하면 다음과 같이 jacocoTestReport이 생성됩니다. 

그리고 알아두어야 할 사항이 있습니다. 바로 test가 먼저 실행된 뒤에 task가 실행되어야 한다는 점입니다. 테스트 성공률을 보는 것이니 당연한 것일까요..? ㅎㅎ 그래야 테스트에 대한 report를 쓸 수 있으니 .. (개인생각) 

실행순서 : test -> jacocoTestReport -> jacocoTestCoverageVerification

다음과 같이 설정하면 test 다음에 jacocoTestReport를 실행하도록 설정할 수 있습니다. 

test {
    // finalizedBy : 이(test) 작업에 대해 주어진 종료자 작업을 추가
    finalizedBy jacocoTestReport // test 작업이 끝나고 jacocoTestReport를 실행
}
jacocoTestReport { 
    // dependsOn : 이 작업에 지정된 종속성을 추가
    dependsOn test // jacocoTestReport 에 test라는 종속성을 추가
}

 

2. JaCoCo 플러그인 구성

jacoco {
    toolVersion = "0.8.7"
    reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir')
}
  • toolVersion : Jacoco의 jar 버전 설정입니다. 
    • 2021.11.24 기준으로 최신 버전은 0.8.7 이며, 최신 버전 확인은 여기서 할 수 있습니다. 
  • reportsDir : Jacoco report 결과물 디렉토리 설정입니다. 

다음으론 report의 결과물을 설정하는 작업입니다. xml, csv, html 으로 설정할 수 있습니다. 

jacocoTestReport {
    reports {
        xml.required = false
        csv.required = false
        html.outputLocation = layout.buildDirectory.dir('jacocoHtml')
    }
}
  • required : 이전엔 enabled로 쓰였던 속성으로 생성 여부를 결정하는 플래그입니다. 
  • outputLocation : 보고서를 생성할 파일 시스템의 위치입니다. 

기본설정이기도 하지만 보기 쉬운 html로 report를 보는 것으로 설정하였습니다. 원하시는 파일이 있다면 false로 되어있는 값을 true로 변경하시면 됩니다. 

 

3. Code Coverage 측정 항목 정의

JacocoCoverageVerification 는 코드 커버리지 측정을 구성 규칙에 따라 충족되는 경우를 확인하는 데 사용할 수 있습니다. violationRules 을 통해 rule 을 정의할 수 있습니다. 정의된 rule 중 하나라도 충족되지 않으면 build가 실패합니다. 

 

제가 글 초반에 언급했던 테스트 코드의 성공률이 50% 가 넘어야 Build 성공하게끔 하는 설정을 여기서 하는건가봅니다. 한 번 살펴보고 적용시켜보겠습니다.

jacocoTestCoverageVerification {
    violationRules {
        rule {
            limit {
                minimum = 0.5
            }
        }

        rule {
            enabled = false
            element = 'CLASS'
            includes = ['org.gradle.*']

            limit {
                counter = 'LINE'
                value = 'TOTALCOUNT'
                maximum = 0.3
            }
        }
    }
}
  • rule : 룰을 정의합니다. 
  • enabled : true 로 설정하면 포함된 작업에 대한 데이터가 수집됩니다. 
  • element : Java 요소의 유형을 나타냅니다. (BUNDLE, CLASS, GROUP, METHOD, PACKAGE, SOURCEFILE)
  • limit : rule 에 대한 제한을 설정합니다. 
    • counter : 커버리지 측정 단위를 설정합니다. (BRANCH, CLASS, COMPLEXITY, INSTRUCTION, LINE, METHOD)
    • minimum :  제한에 대한 최소 예상값을 설정합니다. counter 값을 value 에 맞게 표현했을 때 최솟값을 말합니다. 이 값을 통해 jacocoTestCoverageVerification 의 성공 여부가 결정됩니다.
    • maximum : 제한에 대한 최대 예상값을 설정합니다.
    • value : 측정한 counter의 정보를 어떠한 방식으로 보여줄지 정합니다. (TOTALCOUNT, COVEREDCOUNT, MISSEDCOUNT, COVEREDRATIO,MISSEDRATIO )
  • includes : 검사에 포함되어야 하는 요소 목록입니다. 비워두면 모든 요소가 포함됩니다. 기본값은 [*]입니다.

 

4. 적용해보기

위에 설명했던 내용은 공식문서에 나와있는 예제코드로 작성한 것이고 실제 제가 적용한 build.gradle은 다음과 같습니다. 

plugins {
	id 'org.springframework.boot' version '2.5.5'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
	id 'jacoco'
}
jacoco {
	toolVersion = "0.8.7"
	reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir')
}
group = 'me.whiteship'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'junit:junit:4.13.1'
	runtimeOnly 'com.h2database:h2'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

jacocoTestReport {
	reports {
		xml.required = false
		csv.required = false
		html.required = true
	}
}
test {
	// finalizedBy : 이(test) 작업에 대해 주어진 종료자 작업을 추가
	finalizedBy jacocoTestReport // test 작업이 끝나고 jacocoTestReport를 실행
	useJUnitPlatform()
}
jacocoTestReport {
	// dependsOn : 이 작업에 지정된 종속성을 추가
	dependsOn test // jacocoTestReport 에 test라는 종속성을 추가
    finalizedBy 'jacocoTestCoverageVerification'
}

jacocoTestCoverageVerification {
	violationRules {
		rule {
			enabled = true;
			element = 'CLASS'

			limit {
				counter = 'METHOD'
				value = 'COVEREDRATIO'
				minimum = 0.5
			}
		}

	}
}

현재 제 프로젝트 구조는 다음과 같습니다. 

Repository와 Book, BookStatus, BookService가 존재하지만, Test 코드는 BookService만 만들었습니다. (그러니 당연히 테스트는 실패하겠죠,,^^)

 

./gradlew test

위의 명령어를 사용하여 jacocoTestCoverageVerification을 실행했습니다. 코드 커버리지 검사가 실패하여 Build 도 실패한 것을 볼 수 있습니다. 

그리고 다음과 같이 JaCoCo 레포트가 나온 것을 볼 수 있습니다. 

이처럼 JaCoCo를 통해 최소 테스트 통과 단위 규정을 만들어 빌드 성공여부를 설정할 수 있습니다. 

 

 

댓글