Code/Test

[단위 테스트] 1-2. 단위 테스트의 목표: 커버리지 지표

noahkim_ 2025. 1. 6. 22:26

블라디미르 코리코프 님의 "단위 테스트" 책을 정리한 포스팅입니다.


1. 테스트 스위트 품질 측정

커버리지 지표

  • 테스트 스위트가 소스 코드를 얼마나 테스트하는 지를 백분율로 나타내는 지표
  • 테스트 스위트의 품질을 평가하는데 자주 사용됨


종류

항목 설명
코드 커버리지
- (실행된 코드 라인 수) / (전체 코드 라인 수)
- 코드가 얼마나 테스트되었는지를 측정함
분기 커버리지
- (통과한 분기 수) / (전체 분기 수)
- 조건문(if, switch)의 모든 분기 실행 여부 측정
- 코드 커버리지보다 더 정밀하고 정확한 테스트 평가 가능

 

예시) 분기 커버리지

더보기
public boolean isEligibleForDiscount(int age, boolean hasCoupon) {
    if (age >= 18) { // 분기 1
        if (hasCoupon) { // 분기 2
            return true;  // 조건이 모두 참일 때
        } else {
            return false; // 나이 18 이상이고, 쿠폰이 없을 때
        }
    } else {
        return false; // 나이가 18 미만일 때
    }
}

 

번호 입력 값 실행된 분기
테스트 1 age = 20
hasCoupon = true
첫 번째 분기: 참
두 번째 분기: 참
테스트 2 age = 20
hasCoupon = false
첫 번째 분기: 참
두 번째 분기: 거짓
테스트 3 age = 15
hasCoupon = true
첫 번째 분기: 거짓
테스트 4 age = 15
hasCoupon = false
첫 번째 분기: 거짓
  • 전체 분기 수: 3개 (age >= 18, hasCoupon)
  • 100% 분기 커버리지
    • 전체 분기 커버리지를 달성하려면 모든 조건문이 참/거짓인 경우를 다 테스트해야 함
    • 위 4개의 테스트 스위트는 모든 분기의 테스트를 커버함

 

문제점

  • 모든 가능한 결과를 검증한다 보장할 수 없음
더보기
public class LoginService {
    public String login(String username, String password) {
        if ("user1".equals(username) && "password123".equals(password)) {
            return "Login successful";
        }
        return "Login failed";
    }
}

 

  • 입력 조합: 모든 경우를 테스트코드로 커버하는데 한계가 있음
  • 상태 변화: 사용자가 로그인한 후 세션 유지 등 여러 상태 변화에 대한 테스트도 해야 하지만 모두 포함하는데 한계가 있음
  • 외부 라이브러리를 고려할 수 있는 커버리지 지표가 없음
더보기
@Test
public void testIsValidInput() {
    assertTrue(isValidInput("abcdef"));  // 단일 입력값만 테스트
}

private boolean isValidInput(String input) {
    return StringUtils.isNotEmpty(input) && input.length() > 5;
}
  • 내부적으로 여러 조건을 확인하며 작동하지만, 테스트 커버리지에 포함되지 않음
  • 내부 코드 경로에서 발생할 수 있는 에러가 검증되지 않음
  • ex) null, "", 정수가 아님

 

2. 성공적인 테스트 스위트

항목 설명
개발 주기에 통합
- 코드 변경 시 테스트 작성: 코드가 변경될 때마다, 아무리 작은 변경이라도 테스트 스위트를 작성하고 실행해야 함
- 빌드 시스템에 통합: 코드 변경 시마다 자동으로 실행되도록 해야 함
중요한 부분만을 대상으로 - 비즈니스 로직에 집중: 중요한 부분인 도메인 모델, 알고리즘을 중심으로 테스트 작성
- 인프라 및 외부 종속성: 테스트 코드에서 분리하고, 해당 부분은 모의 객체를 사용
최소 유지비용, 최대 가치
- 가치 있는 테스트 식별 및 작성: 테스트는 가치 있는 부분에 집중
- 유지비용을 최소화: 최대의 가치를 추구
- 좋은 코드 설계 필요: 좋은 테스트 코드를 작성하기 위해서는 코드베이스의 설계가 잘 되어 있어야 함