분기·결정 커버리지로 테스트 품질 게이트 설계하기

분기·결정 커버리지의 산정 방식과 도구별 차이, CI 임계치 운영, 예외 경로 테스트 및 리포트 해석 방법을 정리합니다.

2026-08-14 · 최초 발행 2025-12-22

분기마다 어느 경로가 실행됐는지 확인하는 지표

분기 커버리지(Branch Coverage)는 제어 흐름의 모든 분기에서 각 결과 경로가 최소 1회 이상 실행됐는지를 측정한다. truefalse, 각 case, catch 경로가 대상이 된다.

결정 커버리지(Decision Coverage)는 각 결정문이 truefalse를 모두 경험했는지에 초점을 둔다. 실무 도구와 문서에서는 두 용어를 같은 개념처럼 쓰는 경우도 있다. 다만 switch, catch 등을 분기로 계산하는 범위는 도구마다 다를 수 있다.

산식은 다음과 같다.

Branch Coverage(%) = 커버된 분기 수 / 전체 분기 수 × 100

분기로 계산될 수 있는 대상에는 if/else, else-if 사슬, switch/match의 각 casedefault, 삼항 연산자, 논리 단락 평가, try에서 catch/finally로 이어지는 예외 흐름이 있다. 어떤 대상을 분기로 보는지는 도구별 해석 차이를 확인해야 한다.

신규 코드나 변경 라인에는 90% 이상을 목표로 둘 수 있다. 레거시 전체 코드라면 70~85%를 현실적인 목표로 삼고, 위험도가 높은 컴포넌트부터 기준을 높이는 방식이 가능하다.

분기 수와 실제 타격 경로를 읽는 방법

계측은 결정 지점 단위로 수행한다. if/else, switch/match, 삼항 연산, 단락 평가(and/or), catchfinally가 포함될 수 있다. 루프 역시 반복 횟수가 아니라 진입과 탈출이라는 분기 경로가 충족됐는지로 판단한다.

전체 분기 수는 정적 분석 또는 바이트코드·IR 단위 계측에서 추출된다. 테스트가 실제로 통과한 분기 경로 수가 분자가 된다. 비도달 코드가 분모에 포함되면 목표가 왜곡될 수 있으므로 필터링 정책이 필요하다.

Java에서는 JaCoCo와 IntelliJ, JavaScript·TypeScript에서는 Istanbul/nyc, Python에서는 coverage.py와 pytest-cov, C/C++에서는 gcov/lcov를 사용할 수 있다. 소스 맵핑, 멀티 런·멀티 잡의 병합 리포트, 변경 라인 커버리지 지원 여부도 함께 확인할 항목이다.

분기 커버리지가 100%여도 결함이 없다는 뜻은 아니다. 복합 조건의 논리 결함, 경계값 누락, 타이밍과 동시성 문제는 남을 수 있다. 논리식 내부 조건이 가려지는 masking 문제가 중요하다면 Condition Coverage 또는 MC/DC를 병행한다.

CI 게이트와 회귀 테스트에 연결하기

변경 라인 커버리지 90% 이상과 모듈 단위 80% 이상을 함께 적용하면, 변경분과 전체 품질을 분리해 관리할 수 있다. PR마다 리포트 코멘트를 자동화하고, 기준 미달 시 테스트 보강 워크플로우를 실행하는 방식이다.

리팩토링 전후에는 분기 커버리지와 분기 목록의 diff를 비교한다. 커버리지 회귀가 감지되면 변경 범위를 기준으로 테스트를 자동 생성하거나 보강할 수 있다.

결함을 수정할 때는 해당 분기 경로만을 대상으로 한 테스트를 추가하고, 같은 분기에서의 재발을 막을 회귀 테스트 세트로 확정한다. 위험 기반으로 접근한다면 Cyclomatic Complexity 상위 20% 모듈의 분기 커버리지를 먼저 높이고, I/O·통신처럼 예외 흐름이 많은 경로에서는 catch/finally 분기 타격률을 모니터링한다.

변경 라인 기준 90% 임계치를 적용하면 배포 후 결함 유입률이 2040% 감소한 경험치가 있으며, 테스트 누락 탐지 시간 단축과 PR 평균 리드타임 1020% 단축도 가능하다. 테스트 설계 품질과 예외 처리 시나리오의 가시성이 높아지고, 팀 합의에 기반한 품질 게이트를 정착시키는 데도 도움이 된다.

커버리지 수집부터 피드백까지의 흐름

입력은 테스트 스위트, 계측 설정, 임계치 정책이다. 계측을 적용해 실행 로그를 수집하고, 분기 카운터를 집계해 변경 라인과 매칭한다. 이후 CI 게이트에서 기준을 검증하고 리포트를 피드백으로 제공한다.

출력은 커버리지 리포트, 미충족 분기 목록, 보강 테스트 계획이다. 비도달 코드가 발견되면 분모 제외 정책을 협의하고, 생성 코드와 서드파티 코드에는 필터링 규칙을 적용한다. 플래키 테스트 때문에 분기가 타격되지 않을 때는 재시도와 시드 고정을 검토한다.

아니오통과실패테스트 입력(스위트, 시드,구성)계측 적용('Instrumentation')실행 런타임 수집(분기카운터 기록)분기 탐색 여부(T/F, case,catch)카운터 증가 타임스탬프 기록카운터 변화 없음리포트 생성(분모/분자 계산)CI 임계치 검증(예: 변경 라인90%)병합/배포 단계 진행피드백 발송/테스트 보강

커버리지 기법별 측정 범위와 비용

구분 측정 단위 달성 난이도 결함 발견력 규모 영향(시간/비용) 실무 임계치 가이드
Statement 실행된 문장 낮음 낮음~보통 낮음 80%+
Branch/Decision 분기 경로(T/F, case, catch) 보통 보통~높음 보통 변경 라인 90%+, 전체 80%
Condition 개별 조건(피연산자) 보통~높음 높음 보통~높음 위험 영역 85%+
MC/DC 조건 독립 영향 높음 매우 높음 높음 안전/임베디드 영역 한정
Path 전체 경로 매우 높음 최고 매우 높음 연구/핵심 경로 제한 적용

Python에서 분기 커버리지를 수집하는 예시

환경은 Python 3.10+, pytest 7+, pytest-cov 4+, coverage.py 7+를 기준으로 한다.

app.py

def classify(x: int, y: int) -> str:
    # 분기 1: 단락 평가(and)
    if x > 0 and y > 0:
        return "PP"
    else:
        return "OTHER"

def route(code: int) -> str:
    # 분기 2: match-case (Python 3.10+)
    match code:
        case 0:
            return "ZERO"
        case 1:
            return "ONE"
        case _:
            return "OTHER"

test_app.py

from app import classify, route

def test_classify_pp():
    assert classify(1, 1) == "PP"   # if-true 분기 타격

def test_classify_else():
    assert classify(-1, 1) == "OTHER"  # if-false 분기 타격

def test_route_cases():
    assert route(0) == "ZERO"  # case 0 분기
    assert route(1) == "ONE"   # case 1 분기
    assert route(2) == "OTHER" # default 분기

다음 명령으로 분기 커버리지를 포함한 누락 항목을 확인할 수 있다.

pytest -q --cov=./ --cov-branch --cov-report=term-missing

classifytrue/false 분기와 routecase 0/1/default 분기가 타격되면 높은 분기 커버리지를 확보할 수 있다. switch/match의 분기 계산 방식은 도구별로 차이가 있을 수 있다.

높은 수치를 품질로 오해하지 않기

변경 라인 기준의 임계치를 먼저 적용하고, 전체 임계치는 점진적으로 올린다. catch, timeout, 네트워크 실패처럼 예외 흐름을 테스트에 포함해야 실제 위험을 더 넓게 다룰 수 있다. 비결정적 요소는 시드를 고정하고 재시도 전략을 최소화해 플래키 원인을 줄인다.

커버리지는 단독 지표로 쓰지 않는다. Mutation Testing과 정적 분석을 병행해야 한다. 높은 임계치는 단기 생산성을 낮출 수 있지만 장기 결함 비용 절감 효과가 있으며, 세밀한 분기 측정은 리포트 해석 비용과 문서화·교육 부담을 높인다. 생성 코드나 프레임워크의 분기까지 포함하면 허수가 늘어나므로 필터링 규칙이 필요하다.

분기 커버리지결정 커버리지테스트 자동화품질 게이트회귀 테스트