화이트박스 테스트: 코드 흐름과 커버리지로 검증하는 방법

화이트박스 테스트의 제어 흐름·데이터 흐름 검증 방식과 커버리지, 변이 테스트, CI 품질 게이트 운영 방법을 정리한다.

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

코드 경로를 기준으로 결함을 찾는 테스트

화이트박스 테스트(White-box Testing)는 프로그램의 내부 구조를 공개한 상태에서 제어 흐름, 데이터 흐름, 예외 처리 경로를 따라 테스트 케이스를 설계하는 기법이다. 외부 동작만 확인하는 데 그치지 않고, 어떤 분기와 조건이 실행됐는지까지 검증 대상에 포함한다.

이 방식은 로직 결함을 일찍 찾고 변경 영향 범위를 줄이는 데 적합하다. 테스트의 신뢰도와 재현성을 확보하는 것도 목표다. 품질 지표로는 구문(Statement), 분기(Branch), 조건(Condition), 조건/결정(MC/DC), 경로(Path) 커버리지를 사용한다.

커버리지와 복잡도를 함께 다루는 방식

테스트 설계는 대상 함수나 모듈의 제어 흐름 그래프(CFG)를 확인하고 커버리지 목표를 잡는 일에서 시작한다. 에러 처리, 동시성, 경계값처럼 위험도가 높은 영역에는 테스트를 집중한다.

정적 분석은 데드 코드, 널 참조, 사이클로매틱 복잡도를 찾는 데 쓰인다. 복잡도 임계치를 넘는 함수는 분해나 리팩토링이 필요한 신호가 될 수 있다.

테스트 실행 시에는 커버리지를 계측해 라인과 브랜치 히트맵을 만들고, CI 파이프라인에서는 이를 품질 게이트와 회귀 리포트로 연결한다. 외부 I/O, 시간, 랜덤성, 네트워크는 모킹이나 스텁으로 분리한다. 의존성을 주입하고 순수 함수화를 적용하면 결정적(Deterministic) 실행에 가까워져 flaky 테스트를 줄일 수 있다.

변이 테스트도 함께 활용할 수 있다. 소스에 인위적인 변이를 넣고 테스트가 이를 검출하는지 확인해 테스트 강도를 측정한다. 변이 점수를 바탕으로 부족한 테스트와 취약 경로를 보완한다.

변경과 실패 경로를 검증할 때

레거시 시스템을 리팩토링할 때는 기존 동작을 보존하는 Characterization 테스트를 작성하고 분기 커버리지 80% 이상을 확보하는 방식으로 안전망을 만들 수 있다. 이후에는 커버리지 회귀를 막는 품질 게이트를 둔다.

금융·임베디드·의료처럼 신뢰성이 중요한 영역에서는 MC/DC로 안전 관련 로직의 조건과 결정 조합을 검증한다. 예외 처리와 에러 핸들러 경로, 페일세이프 동작도 체계적으로 점검 대상에 넣는다.

마이크로서비스에서는 트랜잭션 경계, 롤백 경로, 락 경합, 타임아웃 처리를 검증한다. 사가 패턴의 보상 트랜잭션은 실패·재시도·중복 방지 로직까지 테스트해야 한다.

브랜치 빌드에서는 라인≥85%, 분기≥70%, 변이≥60% 기준을 적용할 수 있다. 임계치를 넘지 못하면 병합을 차단하고 자동 이슈를 생성한다.

분석부터 재시험까지의 흐름

입력으로는 요구사항, 소스 코드, 아키텍처 다이어그램, 위험도 평가 결과를 사용한다. 제어 흐름과 데이터 흐름을 분석한 뒤 경로·경계·예외 중심으로 테스트 케이스를 설계한다. 테스트 더블과 계측을 설정해 자동화 실행을 수행하고, 필요하면 변이 테스트를 추가한다.

결과물은 커버리지와 변이 점수 리포트, 결함 목록, 품질 게이트 판정, 갱신된 회귀 테스트 세트다. 결함은 triage하고 리팩토링한 뒤 다시 시험한다.

커버리지가 부족하면 누락된 라인과 분기를 자동으로 식별해 테스트 생성 큐에 등록한다. 변이 점수가 낮으면 살아남은 변이 패턴을 분석한다. 경계 검증이나 예외 검증이 빠진 경우를 보완하는 식이다. 동시성 오류는 데드락·경합 재현 스케줄러로 재시험하고, 타임아웃 증가와 락 순서 정정을 적용한다.

트랜잭션 경계 안에서는 원자성을 검증하고 고립수준별 팬텀 리드와 더티 리드를 재현해 본다. 락 획득 순서의 일치성, 백오프·재시도 정책, 회로차단기 연계도 확인 대상이다.

블랙박스 테스트와 보는 지점의 차이

지표 화이트박스 테스트 블랙박스 테스트
성능 단위 기준 빠른 실행, 계측 오버헤드 존재 시나리오 길이에 비례해 느림
확장성 코드 변경 시 테스트 갱신 비용 상승 요구 변경 중심, 영향 상대적으로 완만
일관성 구현 변경에 민감, 리팩토링 영향 큼 외부 인터페이스 기준 안정적
안정성 로직 결함 검출 민감도 높음 사용자 시나리오 결함 포착 강점
운영 편의 계측·변이·정적 분석 도구 필요 도구 의존도 낮음, 설계 용이

pytest와 coverage로 확인하는 예시

전제조건은 Python 3.10+, pytest 7+, coverage.py 7+이다.

소스 코드: shipping.py

import math

def calc_shipping_fee(weight: float, is_fragile: bool) -> int:
    if weight <= 0:
        raise ValueError("invalid weight")
    base = 5000 if is_fragile else 3000
    if weight > 10:
        rate = 1500
    elif weight > 2:
        rate = 1000
    else:
        rate = 500
    return base + rate * math.ceil(weight)

테스트: test_shipping.py

import pytest
from shipping import calc_shipping_fee

@pytest.mark.parametrize("w,is_fragile,expected", [
    (1.2, False, 3000 + 500 * 2),   # 소형, 비취급주의
    (3.0, False, 3000 + 1000 * 3),  # 중형 경계
    (10.1, True, 5000 + 1500 * 11), # 대형, 취급주의
])
def test_normal_cases(w, is_fragile, expected):
    assert calc_shipping_fee(w, is_fragile) == expected

def test_invalid_weight():
    with pytest.raises(ValueError):
        calc_shipping_fee(0, False)

실행과 커버리지 측정은 다음 명령으로 수행한다.

pytest -q --maxfail=1 --disable-warnings
pytest --cov=shipping --cov-branch -q
coverage html  # htmlcov/index.html 리포트 생성

품질 게이트 예시는 다음과 같다.

coverage run -m pytest -q
coverage report --fail-under=85

변이 테스트는 선택적으로 적용한다. Python에서는 mutmut 또는 mutatest를 도입하고 라인 타깃을 제한해 실행 시간을 관리한다. 명령 예시는 mutmut run --paths-to-mutate shipping.py --tests-dir . --backup이다.

품질 게이트에서 반복되는 보강 흐름

커버리지와 변이 점수는 함께 봐야 한다. 내부 구조의 실행 범위를 넓히는 것만으로는 테스트가 실제 결함을 잡아내는지 충분히 판단하기 어렵기 때문이다.

화이트박스 테스트를 운영하면 결함 유출률 30~60% 감소, 회귀 결함 재발률 40% 이상 감소를 기대할 수 있다. 변경 실패율(Change Failure Rate) 하락과 평균 복구시간(MTTR) 단축도 기대 효과에 포함된다. 리팩토링에 대한 자신감이 높아지고, 복잡도 관리에 기반한 구조 개선과 실패 재현성, 근본 원인 파악 속도도 개선된다.

아니오아니오소스 코드정적 분석 복잡도 산출단위 테스트 실행(계측 포함)커버리지 = 85%?변이 테스트 실행테스트 케이스 보강 리팩토링변이 점수 = 70%?품질 게이트 통과 병합/배포취약 경로보강(경계/예외/동시성)
화이트박스 테스트코드 커버리지변이 테스트정적 분석품질 게이트