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;
}
  • StringUtils 내부의 조건문 실행 여부는 커버리지 지표에 반영되지 않음
  • 에러 유발 케이스 테스트가 누락되기 쉬움 (null, "", 정수 아님)

 

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

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