cloudwithbass

[Jenkins] 코드 커버리지란?, JaCoCo와 Checkstyle 본문

Docker and Jenkins

[Jenkins] 코드 커버리지란?, JaCoCo와 Checkstyle

여영클 2024. 7. 17. 16:55

    목차

      • 지난 포스팅에서 Jenkinsfile을 이용해 컴파일과 단위 테스트를 실행하는 파이프라인을 구성했습니다.
      • 그러나 단위 테스트만으로는 코드의 동작이 문제 없다고 보장할 순 없습니다.
      • 따라서 이번 포스팅에선 코드 커버리지와 정적 코드 분석에 대해 다루겠습니다.

      1. 코드 커버리지란?

      • 코드 커버리지는 테스트 코드가 전체 소스 코드의 얼마나 많은 부분을 테스트하는지 나타내는 지표입니다.
      • 커버리지 비율이 높을수록 테스트의 신뢰도가 높아지겠지만, 그만큼 테스트 코드를 작성하는 데 시간과 노력이 필요할 것입니다.

      1-1 코드 커버리지 적정 수준 

      Google Testing Blog에선 보편적인 커버리지 수치는 존재하지 않지만, 일반적으로 커버리지 비율이 60%일 경우 '적절 수준(acceptable)', 75%일 경우 칭찬할 만한 수준(commendable)', 90%일 경우 '모범적인 수준(exemplary)'이라고 소개했습니다.

       

      자바의 경우 코드 커버리지를 측정하는 도구는 JaCoCo, 오픈클로버 등이 있지만 여기서는 JaCoCo를 활용하겠습니다.


      1-2. gradle 구성 추가와 리포트 생성

      build.gradle의 plugin에 id 'jacoco' 추가

       

      build.gralde에 다음 내용을 추가합니다.

      이제 ./gradlew test jacocoTestCoverageVerification 명령을 실행하면 커버리지의 최솟값을 20%로 설정합니다.

      즉, 20% 이상 커버하지 않는 경우 실행을 실패시킵니다.

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

       

      최솟값 설정

       

       

       

      ./graldew test jacocoTestReport 명령으로 테스트 리포트 생성 후, build/reports/jacoco/test/html/index.html 경로에서 테스트 커버리지 리포트를 확인할 수 있습니다.

      • 아래 사진처럼 코드가 커버하는 Instruction, Branch (if, switch 등), Method, Class 등을 확인할 수 있습니다. 
      • 제 경우 커버하는 Instruction의 비율은 46%입니다.
      • 정상적인 경우, 사진의 색깔로 커버하는 부분과 커버하지 않는 부분의 비율을 표시하지만 저는 html 문서를 그대로 브라우저로 확인해서 이미지를 로드하지 못 했습니다.

       


      1-3. 파이프라인 스테이지에 코드 커버리지 추가

      Jenkinsfile에 Code coverage 스테이지를 추가합니다.

      stage("Code coverage"){
                  steps{
                      sh "./gradlew jacocoTestReport"
                      sh "./gradlew jacocoTestCoverageVerification"
                  }
      }

       

       

      Jenkinsfile을 깃 푸시하고 젠킨스에서 파이프라인을 빌드하면 다음과 같이 빌드가 성공한 모습을 볼 수 있습니다.


      2. 정적 코드 분석

      • 코드 자체의 품질을 보증하는 방법입니다.
      • 예를 들어 다음과 같은 코드 품질을 검사할 수 있습니다.
        •  '모든 public 클래스는 javadoc 주석이 있어야 한다'
        •  '한 줄에 입력 가능한 최대 글자 수를 120자로 제한한다'
        •  'equals() 메서드를 정의하는 클래스를 반드시 hashCode() 메서드도 정의해야 한다'

       

      자바 언어에서 가장 많이 사용되는 정적 분석 도구인 체크스타일로 실습을 진행하겠습니다.


      2-1 체크스타일 구성

      build.gradle의 플러그인에 checkstyle을 추가합니다. 

      다음으로  config/checkstyle/checkstyle.xml 경로에 다음 파일을 작성합니다.

      ConstantName 모듈은 상수이름이 대문자와 언더 스코어(_)만으로 이루어져있는지 검사합니다.

      <?xml version="1.0"?>
      <!DOCTYPE module PUBLIC
        "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
        "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
      
      <module name="Checker">
        <module name="TreeWalker">
          <module name="ConstantName" />
        </module>
      </module>

       

      테스트를 위해 CalculatorApplication에 소문자로 이루어진 상수를 추가하겠습니다.


      2-2. 체크스타일 테스트

      ./gradlew checkstyleMain 명령으로 테스트 결과, 예상한대로 패턴이 일치하지 않는다는 에러와 함께 정적 코드 검사에 실패했습니다.

       

      이제 다시 정적 코드 검사 또한 Jenkinsfile의 스테이지에 추가해서 파이프라인을 빌드해보겠습니다.

      역시 같은 이유로 빌드에 실패했습니다.

       

       

      이로써 파이프라인에선 깃허브의 코드를 가져와 컴파일하고, 단위 테스트와 코드 커버리지, 정적 코드 분석까지 자동화할 수 있게 됐습니다.

       


      참고 문서

      우아한 형제들 기술 블로그 - Gradle 프로젝트에 JaCoCo 설정하기

      LG유플러스 기술 블로그 - Code Coverage

      Google Testing Blog - Code Coverage Best Practice