테스트 커버리지 종류완벽 정리 - 구문 커버리지, 분기 커버리지 , 조건/분기 커버리지, 경로커버리지, 다중조건 커버리지

테스팅을 할때도 테스트의 범위를 지정해야하는데 이때  어디서부터 어디까지 또 어떻게 테스트를 할것인지에 대한 구분을 지은 종류가 있습니다.

오늘은 해당 종류를 예시와 같이 알아보겠습니다.

테스트 커버리지의 종류

1.구문 커버리지 (Statement Coverage)

설명:
프로그램의 모든 실행 가능한 문장(라인)이 최소 한 번 이상 실행되었는지를 측정하는 가장 기본적인 커버리지 기준입니다.

목표:
코드의 모든 문장이 실제로 실행되었는지를 확인합니다.

즉 간략하게 말해서 프로그램의 모든 라인을 전부 실행하는것이 해당 커버리지라고 할수 있습니다.

모든라인 실행
코드 예시
export function add(a: number, b: number) {
    // 구문(Statement) 커버리지: 이 한 줄이 실행되면 카운트
    return a + b;
  }

 2.분기 커버리지 (Branch Coverage)

설명:
프로그램 내의 모든 결정 지점(if, while, for 등)에서 참(True)과 거짓(False) 양쪽 분기가 최소 한 번씩 실행되었는지를 측정합니다.

목표:
코드의 모든 제어 흐름(분기)이 테스트되었는지 검증합니다.

if 나 for 같은 코드에서 양쪽 전부 한번씩 실행
코드 예시
  export function classify(n: number): 'NEG' | 'ZERO' | 'POS' {
    // 분기(Branch) 커버리지: if, else if, else 각각의 분기를 모두 타야 100%
    if (n < 0) return 'NEG';
    else if (n === 0) return 'ZERO';
    else return 'POS';
  }

 3.조건 커버리지 (Condition Coverage)

설명:
복합 조건문(if (A && B))에서 각 개별 논리 조건(A, B)이 각각 참(True)거짓(False) 값을 모두 가졌는지를 측정합니다.

목표:
각 조건이 전체 결정 결과에 미치는 영향을 검증합니다.

각 개별 조건이 양쪽 다 한번 이상씩 실행되는지 확인
코드 예시
  export function isTeenager(age: number): boolean {
    // 조건(Condition) 커버리지: 각 조건식(age >= 13, age <= 19)이 true/false 모두 평가되어야 함
    return age >= 13 && age <= 19;
  }
 

 4.조건/분기 커버리지 (Condition/Decision Coverage)

설명:
조건 커버리지분기 커버리지를 동시에 만족하는 기준으로, 두 가지의 장점을 결합한 형태입니다.

목표:
각 조건이 다양한 조합으로 분기 결과에 미치는 영향을 종합적으로 검증합니다.

조건과 분기를 둘다 만족, 모든 분기가 실행되면서 개별 조건들의 true/fale가 전부 한번이상은 실행되어야함
코드 예시
  export function accept(country: string, isAdult: boolean): 'ALLOW' | 'DENY' {
    // 분기조건(Branch Condition) 커버리지: 분기(if)의 결과가 true/false 모두 발생해야 함
    if (country === 'KR' && isAdult) {
      return 'ALLOW';
    }
    return 'DENY';
  }

 5.다중 조건 커버리지 (Multiple Condition Coverage, MCC)

설명:
하나의 분기문 내 모든 개별 조건들의 가능한 모든 조합(True/True, True/False, False/True, False/False 등)이 테스트되었는지를 측정합니다.

목표:
복합 조건문에서 발생할 수 있는 모든 오류 시나리오를 철저히 검출합니다.

하나의 조건문 안에 여러 조건이 있으면 해당 조건들의 모든 경우의 수를 테스트함
코드 예시
 
  export function canRegister(user?: { email?: string; phone?: string; agree?: boolean }): boolean {
    // 다중조건(Multiple Condition) 커버리지: 각 원자 조건이 true/false 조합을 충분히 커버
    if (!user) return false;
 
    const hasEmail = !!user.email;
    const hasPhone = !!user.phone;
    const agreed = user.agree === true;
 
    // 등록 조건: 이메일 또는 휴대폰이 있어야 하고, 동의해야 함
    return (hasEmail || hasPhone) && agreed;
  }
 

 6.경로 커버리지 (Path Coverage)

설명:
프로그램의 시작점부터 종료점까지 도달 가능한 모든 독립적인 경로가 최소 한 번 이상 실행되었는지를 측정합니다.

특징:
이론적으로 가장 강력한 커버리지 기준이지만, 경로의 수가 기하급수적으로 증가하므로 실제 적용은 복잡하거나 비실용적일 수 있습니다.

프로그램의 실행경로 중 모든 경로를 실행해야함
코드 예시
  export function route(state: 'INIT' | 'LOADED' | 'ERROR', retry: boolean): number {
    // 경로(Path) 커버리지: 가능한 실행 경로(조합)를 모두 실행
    // 가능한 경로 예:
    // 1) INIT + retry=false → 1
    // 2) INIT + retry=true  → 2
    // 3) LOADED             → 3
    // 4) ERROR              → 4
    if (state === 'INIT') {
      if (retry) return 2;
      return 1;
    } else if (state === 'LOADED') {
      return 3;
    } else {
      return 4;
    }
  }

 

위처럼 각 테스트 커버리지에 관한 내용을 예시와 같이 알아봤습니다. 기초적인 이론이지만 실제 개발을 하면서도 막연히 테스트하는게 아닌

내가 하고있는게 이런 커버리지 테스트구나 

 

라고 생각하면서 해보시면 더 깨우치는게 많게 되고 왜 이런 방식을 쓰고 어떤 방식이 더 효율적이고 많이 사용하는지 명확하게 정리 될 것 같다고 생각합니다!

반응형