테스트 설계 기법으로 커버리지와 결함 탐지 균형 잡기

동등 분할, 경계값 분석, 결정 테이블, 상태 전이, Pairwise를 활용해 테스트 케이스와 커버리지를 설계하는 방법

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

적은 케이스로 결함을 더 찾기 위한 설계

테스트 설계 기법은 요구사항, 규격, 코드 구조, 사용자 시나리오를 바탕으로 결함을 효과적으로 발견할 테스트 케이스를 만드는 방법론이다. 목표는 단순히 케이스를 많이 작성하는 데 있지 않다. 커버리지 목표를 충족하면서 테스트 수를 줄이고, 위험이 큰 영역을 먼저 검증하며, 요구사항부터 결함까지의 추적성을 확보하는 데 있다.

기법은 검증 근거에 따라 나눌 수 있다.

  • 명세 기반에는 동등 분할, 경계값 분석, 결정 테이블, 상태 전이 테스트가 포함된다.
  • 구조 기반에는 구문·분기·조건·경로 커버리지와 MC/DC 등이 있다.
  • 경험 기반은 오류 추정, 탐색적 테스트, 체크리스트를 활용한다.
  • 조합 기반은 Pairwise(2-wise), n-wise, Orthogonal Array로 입력 조합을 다룬다.

시스템의 성격에 맞춰 기법을 고른다

입력 도메인이 중심인 시스템은 동등 분할과 경계값 분석부터 적용하는 편이 맞다. 반대로 규칙이나 조합이 복잡한 시스템은 결정 테이블과 조합 테스트가 우선순위가 된다.

구조 기반 기법은 코드 변경의 영향 범위를 분석하거나 시큐어 코딩을 검증할 때 적합하다. 아직 알려지지 않은 영역을 탐색하거나 초기 탐사가 필요한 상황에서는 경험 기반 기법이 유용하다. 기법을 고를 때는 시스템 특성뿐 아니라 결함 비용, 요구 정확성, 규칙의 복잡도를 함께 본다.

커버리지 기준도 설계 단계에서 정해야 한다. 요구사항 커버리지, 분기·전이 커버리지, 2-wise 이상의 조합 상호작용 커버리지를 정의하고 종료 조건을 명시한다. 요구사항–테스트–결함 간 추적성 매트릭스(RTM)를 운영하면 변경이 생겼을 때 영향 범위를 자동으로 추적할 수 있다.

위험이 큰 조합과 데이터 검증을 먼저 다룬다

심각도×발생가능성 점수로 테스트 집중 영역을 정하고, 장애 비용이 높은 경계·전이·규칙 교차 영역을 우선 검증한다. Pairwise 같은 샘플링 기법은 케이스 수를 줄이는 데 쓰되, 고위험 조합은 3-wise 이상으로 다뤄야 한다.

테스트 데이터는 경계값, 오류값, 특수값을 포함하는 세트로 표준화한다. 테스트 격리가 필요하면 트랜잭션과 락을 사용한다. 기대 결과를 판정하는 오라클은 결정 테이블을 따르는 규칙 기반 방식, 메타모픽 오라클, SQL 비교를 이용한 데이터 리컨실리에이션으로 설계할 수 있다. 자동화에는 JSON/CSV처럼 다루기 쉬운 포맷이 적합하다.

결정 테이블에서 테스트 케이스를 만들고, 상태 전이 다이어그램에서 경로를 생성하며, 조합 생성기로 Pairwise 세트를 산출할 수 있다. CI 파이프라인과 연결하면 커버리지를 추적하고 변경에 맞춘 재생성을 자동화할 수 있지만, 모델의 정확성과 유지비용은 함께 고려해야 한다.

도메인별 적용 방식

금융 API의 입력 검증에서는 동등 분할, 경계값 분석, 결정 테이블을 조합한다. 입력 필드를 도메인으로 나누고 최소·최대·Null·공백 등의 경계 후보를 만든 뒤, 한도와 권한 규칙을 결정 테이블로 정리한다. 이후 SQL 오라클로 정합성을 검증한다.

상태 기반 임베디드 디바이스는 상태 전이 테스트와 전이 커버리지(Edge Coverage)가 중심이다. 상태도를 작성하고 전이와 가드 조건을 뽑아 최소 전이 커버 세트를 만든 다음, 타이밍과 동시성 예외 시나리오를 추가한다.

이커머스 프로모션 규칙에는 결정 테이블과 Pairwise가 맞는다. 쿠폰, 회원등급, 카테고리, 장바구니 금액 축을 정하고 중복 규칙을 정규화한 뒤 Pairwise로 조합을 줄인다. 가격 임계값은 경계값으로 보강한다.

데이터 마이그레이션 검증에는 층화 샘플링과 메타모픽·리컨실리에이션 오라클을 사용한다. 레코드를 층화해 추출하고 필드 매핑을 결정 테이블로 관리하며, SQL 집계 비교로 합계·카운트·해시를 대조한다. 누락과 잘림은 경계 사례를 넓혀 확인한다.

기법별 설계 특성

기법 성능(설계 효율) 확장성 일관성 안정성 운영 편의
동등 분할 높음 높음 중간 중간 높음
경계값 분석 높음 중간 높음 중간 중간
결정 테이블 중간 중간 높음 높음 중간
상태 전이 중간 낮음 높음 중간 낮음
Pairwise(조합) 매우 높음 높음 중간 중간 높음

성능(설계 효율)은 케이스 수 대비 결함 발견 효율성을 뜻한다. 확장성은 파라미터나 상태가 늘어날 때 설계 복잡도가 어떻게 변하는지, 일관성은 재현 가능한 도출 규칙을 갖췄는지를 본다. 안정성은 변경에 따른 영향을 얼마나 줄일 수 있는지, 운영 편의는 도구 지원과 자동화의 용이성을 가리킨다.

설계부터 환경 원복까지의 흐름

요건 수집 분석분석 결과 전달모호함 있음모호함 없음정의 완료데이터 요구 정의격리 필요일관성 확보예외 발생복구 재시도검증 기준 확정출력 생성환경 정리입력: 요구사항, 리스크 평가,비즈니스 규칙, 시스템 제약처리: 기법 선택(명세기반/구조 기반/경험기반/조합 기반)조건 검사: 요구사항 모호성여부에러 핸들링: 모호성해소(질의/워크샵), '결정테이블' 정형화처리: 커버리지 메트릭정의(분기/전이/조합), 종료기준 설정처리: 테스트 데이터 설계격리(트랜잭션, 락)처리: 'BEGIN TRANSACTION;SELECT ... FOR UPDATE'로데이터 고립처리: 오라클 정의(규칙기반/메타모픽/SQL리컨실리에이션)처리: 테스트 케이스 생성우선순위화(Risk-Based)출력: 테스트 케이스 세트,RTM, 커버리지 리포트에러 핸들링: 롤백/재시도,데이터 픽스 스크립트 적용일관성: 커밋 환경 원복,테스트 독립성 보장

Pairwise와 경계값을 함께 만드는 코드

Python 3.10+ 환경에서 아래 예시는 Pairwise 조합을 생성하고 경계값 후보를 보강한다. 실행 전 pip install allpairspy가 필요하다.

# Python 3.10+
# pip install allpairspy

from allpairspy import AllPairs

# 파라미터 도메인 정의(동등 분할 결과)
params = {
    "membership": ["guest", "silver", "gold"],
    "coupon": ["none", "fixed10", "rate10"],
    "category": ["grocery", "electronics", "fashion"],
    "payment": ["card", "point", "mixed"],
}

# Pairwise 생성
pairs = list(AllPairs(list(params.values())))

# 경계값 후보(금액) 보강
boundary_amounts = [0, 1, 49999, 50000, 50001, 1000000]

# 테스트 케이스 생성
test_cases = []
for comb in pairs:
    for amount in boundary_amounts[:2]:  # 예: 핵심 경계만 포함(0, 50000)
        case = dict(zip(params.keys(), comb))
        case["amount"] = amount
        test_cases.append(case)

print(f"Pairwise 조합 수: {len(pairs)}")
print(f"테스트 케이스 수(경계 포함): {len(test_cases)}")
print(test_cases[:5])  # 샘플 출력

# 오라클 스텁: 할인 규칙 계산 함수 자리표시자
def oracle_expected(amount, membership, coupon, category, payment):
    # 결정 테이블 규칙에 따라 기대값 계산 로직 구현 필요
    # 예: 경계값 검증 중심 간단 규칙
    eligible = amount >= 50000 and coupon != "none"
    return {"eligible": eligible}

# 사용 예
sample = test_cases[0]
expected = oracle_expected(**sample)
print("expected:", expected)

Pairwise 적용에서 기대할 수 있는 변화

각 파라미터가 3값이라고 가정하면 브루트포스 방식은 3^n 케이스가 필요하다. 2-wise는 대략 O(n·3^2) 수준으로 축약된다. n=6에서는 729개가 약 15~20 케이스 수준이 되며, 도메인 제약에 따라 변동하지만 97%± 절감 효과를 기대할 수 있다.

경계값 분석을 더하면 입력 검증 결함 검출률이 체감상 2035%p 상승할 수 있다. 이는 유사 프로젝트 실측 기준의 추정치이며 시스템 성격에 따라 편차가 존재한다. 고위험 규칙을 결정 테이블로 관리하면 누락과 모순을 줄이고 결함 재발률을 낮출 수 있다. 요구–테스트 추적성을 강화하면 변경 영향 영역의 테스트 재생성을 자동화할 수 있고, 테스트 사이클 타임은 2040% 단축될 수 있다.

테스트 설계의 중심은 최소 케이스로 최대 결함을 노리는 샘플링과 커버리지 관리다. 입력 도메인에는 동등 분할과 경계값 분석, 복잡한 규칙에는 결정 테이블, 상태 머신에는 상태 전이, 조합 폭발에는 Pairwise를 적용한다. RTM, 커버리지, 트랜잭션·락 기반의 데이터 격리, 자동화 파이프라인을 하나의 프로세스로 연결해야 한다.

테스트 설계소프트웨어 테스트커버리지Pairwise결정 테이블