Chef.Yeon
Code Cook
Chef.Yeon
전체 방문자
오늘
어제
  • 분류 전체보기 (230)
    • 게임 개발 (1)
      • Unity (1)
    • Android (27)
      • Kotlin (19)
      • 우아한테크코스 5기 (4)
    • Language (11)
      • 파이썬 (3)
      • Java (7)
    • DB (2)
      • SQL (16)
    • Spring (25)
    • 코딩테스트 (56)
    • Git (1)
    • TIL (85)
    • DevOps (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 우아한테크코스
  • til
  • kibana
  • rsocket
  • 안드로이드
  • elasticsearch
  • 코딩테스트
  • ec2
  • 백준
  • 프로그래머스
  • 코틀린 인 액션
  • 레포지토리
  • 내림차순
  • Android
  • java
  • spring
  • kotlin
  • grafana
  • MariaDB
  • 프리코스
  • 에라토스테네스의 체
  • 파이썬
  • webflux
  • 문자열
  • SQL
  • Wil
  • 코틀린
  • Docker
  • enum
  • 다이나믹 프로그래밍

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Chef.Yeon

Code Cook

Spring

[Spring] Jacoco 적용하여 코드 커버리지 확인 및 Codecov사용한 PR에 커버리지 코멘트 추가

2023. 5. 27. 05:22

프로젝트에 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

 

 

https://about.codecov.io/

위 링크로 이동해 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분 정도 걸리기도 한다.)

 

 

728x90

'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
    'Spring' 카테고리의 다른 글
    • [Spring] Webflux + RSocket, React 사용한 전체 채팅 구현
    • [Spring] SpringBoot K6 + Grafana 부하 테스트 및 모니터링
    • [Spring] SpringBoot Prometheus, Grafana를 사용한 모니터링(Feat. Docker)
    • [Spring] Spring WebFlux 간단한 예제
    Chef.Yeon
    Chef.Yeon
    보기 좋고 깔끔한 코드를 요리하기 위해 노력하고 있습니다.

    티스토리툴바