code coverage

jacoco

code coverage

코드 커버리지는 테스트 코드가 실제 애플리케이션 코드에서 몇 퍼센트를 실행했는지 분석하는 지표다

단위 테스트/통합 테스트 실행 후 커버리지를 측정하여 테스트가 부족한 부분을 찾아내고 보완하는 데 사용된다

주의점

100% 커버리지가 완벽한 코드 품질을 의미하지 않는다

mock을 사용한 테스트로 커버리지가 높을 수 있다

로직이 단순한 코드는 커버리지가 낮을 수 있다

코드 커버리지는 자동화된 지표일 뿐이므로 눈으로 직접 논리적 결함을 확인해야 한다

jacoco

jacoco는 자바 애플리케이션에서 테스트 코드가 실제 코드 블록의 몇 퍼센트를 측정하는 코드 커버리지 분석 도구다

테스트가 충분히 실행되었는지 확인하고 부족한 부분을 보완하여 코드 품질을 향상시키는 데 도움을 준다

주요 특징

바이트코드 기반 동작: 바이트코드를 변형하여 코드 실행 여부를 추적한다

빠른 실행 속도: 런타임 오버헤드가 낮아서 빌드/테스트 속도에 미치는 영향이 적다

테스트 프레임워크와의 통합: junit, testng 등 자바 기반 테스트 프레임워크와 호환된다

ci/cd 연동: maven, gradle, sonarqube 등과 연동하여 코드 품질을 관리할 수 있다

보고서 제공: html, xml, csv 형태의 커버리지 보고서를 생성한다

코드 커버리지 측정 기준

라인 커버리지

소스 코드의 각 라인이 최소 한 번 실행되었는지 측정한다

계산 방식: 테스트 코드로 실행된 라인 수 / 전체 코드 라인 수 * 100%

public void example(boolean flag) {
    System.out.println("hello");     // 1

    if (flag) {                      // 2
        System.out.println("test");  // 3
    }
}

테스트 코드가 1만 실행하고 2,3을 건너뛰면 라인 커버리지는 33.3%가 된다

브랜치 커버리지

if, switch, for, while 등 조건문이 모든 경우를 거쳤는지 측정한다

계산 방식: 실행된 분기 수 / 전체 분기 수 * 100%

public void checkNumber(int x) {
    if (x > 0) {   // 분기 1  x > 0
        System.out.println("positive");
    } else {       // 분기 2  x <= 0
        System.out.println("non-positive");
    } 
}

checkNumber(5) 테스트 시 x > 0 분기만 실행되므로 브랜치 커버리지 50%로 측정된다

checkNumber(0) 테스트 시 x <= 0 분기까지 실행되므로 브랜치 커버리지 100%로 측정된다

메서드 커버리지

클래스 내의 모든 메서드가 최소 한 번 실행되었는지 측정한다

계산 방식: 테스트된 메서드의 수 / 전체 메서드 수 * 100%

public class Calculator {

    public int add(int a, int b) {
        return a + b;
    }

    public int subtract(int a, int b) {
        return a - b;
    }
}

add 메서드 테스트 시 메서드 커버리지 50%

add, subtract 메서드 테스트 시 메서드 커버리지 100%

클래스 커버리지

특정 클래스가 한 번이라도 테스트에서 실행되었는지 측정한다

계산 방식: 테스트된 클래스 수 / 전체 클래스 수 * 100%