동등 분할 기법으로 테스트 케이스 설계하기
동등 분할 기법의 유효·무효 클래스 설계, 대표값 선택, 경계값 분석과 페어와이즈 조합 적용 방법을 정리한다.
2026-08-14 · 최초 발행 2025-12-17
입력 공간을 대표값으로 다루는 방법
입력 조합이 늘어날수록 모든 값을 직접 검증하는 방식은 빠르게 감당하기 어려워진다. 동등 분할 기법(Equivalence Partitioning)은 동일한 동작을 일으킬 것으로 보는 입력값 집합을 동등 클래스(Equivalence Class)로 묶고, 각 클래스의 대표값을 선택해 테스트하는 방법이다.
클래스는 시스템이 허용하는 범위·형식·조합을 담는 유효 클래스와, 규칙 위반 및 예외·오류 경로를 다루는 무효 클래스로 나뉜다. 동등 분할로 입력을 그룹화한 뒤에는 경계값 분석(Boundary Value Analysis)을 연결해 각 클래스가 만나는 경계 지점을 더 촘촘히 확인할 수 있다.
요구사항에서 테스트 규칙으로 옮기기
입력 도메인을 설계에 반영하는 과정은 다음 흐름으로 진행된다.
- 요구사항, 스펙, 데이터 사전에서 값의 범위와 형식, 필수·옵션 여부, 상호배타 조건, 종속성을 추출한다.
- 불변식과 전제조건 같은 조건식을 정의하고, 유효·무효 판단 기준을 명확히 적는다.
- 규칙별로 입력 공간을 나눈 뒤 중복되거나 충돌하는 클래스를 병합하고 우선순위를 정한다.
- 각 클래스에서 대표값 1~2개를 고른다. 일반값과 경계 근접값은 구분하며, 모호한 클래스에는 추가 대표값을 둔다.
- 다변수 입력은 페어와이즈(2-wise) 또는 위험 기반 가중 조합으로 구성하고, 반드시 포함하거나 제외할 조합을 관리한다.
- 기대 결과와 에러 코드, 메시지, 상태 변화, 로그·메트릭 기준을 오라클로 정의한다.
- 테스트 케이스와 요구사항을 연결하고, 결함이 발견됐을 때 해당 클래스를 역추적할 수 있도록 식별자를 부여한다.
무효 클래스도 정상 흐름과 같은 비중으로 설계해야 한다. 명시적인 예외·에러 코드·메시지를 확인하고, 보안상 정보 노출을 최소화하며, 트랜잭션 롤백과 상태 일관성까지 검증 대상에 포함한다.
유효·무효 클래스를 함께 설계할 때의 기준
요구사항을 논리 규칙으로 전개하면 입력 도메인을 불연속 구간이나 카테고리로 나눌 수 있다. 이때 규칙 충돌과 중복을 제거해 클래스의 상호 배타성과 완전성을 확보한다.
대표값은 클래스의 전형적인 값을 보여야 한다. 일반적으로 일반 대표값 1개를 택하고, 예외적으로 모호한 클래스에는 추가 1개를 둔다. 경계값은 동등 클래스의 대표값과 혼동하지 않고 별도 테스트로 관리한다.
매개변수가 많아지면 페어와이즈 또는 t-wise로 조합 폭발을 억제한다. 비즈니스 위험이 큰 조합은 가중치를 적용해 반드시 포함한다. 클래스 ID, 규칙 근거, 대표값, 기대 결과를 메타데이터로 남겨두면 pytest나 JUnit의 파라미터라이즈 방식으로 자동 생성하기에도 적합하다.
입력 유형별 분할 예시
나이(age)가 0~120 정수만 허용되는 경우 유효 클래스는 [0–120]이고, 무효 클래스는 (<0), (소수), (>120), (null)로 나눌 수 있다. 유효 대표값은 0, 35, 120이며 무효 대표값은 -1, 121, 3.14, null이다. 경계값 분석에서는 -1/0과 120/121을 추가한다.
이메일 형식이나 비밀번호 정책처럼 길이, 문자군, 금지 패턴을 함께 보는 입력도 클래스 단위로 설계한다. 이메일은 표준 RFC 패턴을 유효 클래스로 두고 공백 포함, 다중 '@', 도메인 누락을 무효 클래스로 분리한다. 각 클래스의 대표 샘플을 정의한 뒤 무효 입력에서는 에러 메시지의 균질성도 확인한다.
배송 옵션이 {일반, 새벽, 당일}이고 국가가 {KR, US, JP}이며 일부 옵션과 국가 조합이 금지되는 경우, 각 축을 먼저 동등 분할한다. 이후 새벽 x 해외 같은 블랙리스트를 적용하고 페어와이즈로 최소 케이스를 선택한다.
GET /search?q처럼 sort∈{asc,desc}, page∈[1..100], filter∈{in-stock, promo}를 함께 받는 API도 같은 방식으로 다룬다. 각 파라미터를 유효·무효로 나누고 빈 q, page=0, sort=xyz 같은 무효 조합을 필수로 포함한다. rate limit과 캐싱 키 충돌 등 비기능 요구도 오라클에 포함한다.
경계값 분석과의 역할 분담
| 항목 | 동등 분할(EP) | 경계값 분석(BVA) |
|---|---|---|
| 성능(탐지 효율/케이스) | 광범위 입력을 적은 케이스로 커버 | 임계 결함 탐지 효율 우수 |
| 확장성(변수 증가) | 페어와이즈 연계로 확장성 양호 | 변수 증가 시 케이스 선형~중가 |
| 일관성(규칙성) | 규칙 기반 분할로 일관성 높음 | 경계 정의 정확도에 의존 |
| 안정성(누락/오탐) | 무효 클래스 병행 시 누락 감소 | 경계 외 영역 결함 누락 가능 |
| 운영 편의(자동화) | 파라미터라이즈/데이터 주도에 적합 | 경계 케이스 유지관리 용이 |
동등 분할은 넓은 입력 공간을 줄이는 데 쓰고, 경계값 분석은 그 분할의 경계가 가진 취약점을 확인하는 데 쓴다. 두 기법을 함께 적용하는 편이 적절하다.
Python으로 대표값과 조합 만들기
전제조건: Python 3.11+, 선택적으로 allpairspy(페어와이즈) 2.5.0
# 동등 분할 기반 대표값 선택 및 조합 생성 예시
# 환경: Python 3.11+, pip install allpairspy==2.5.0 (선택)
from itertools import product
try:
from allpairspy import AllPairs # 페어와이즈(선택)
PAIRWISE_AVAILABLE = True
except Exception:
PAIRWISE_AVAILABLE = False
# 1) 규칙 정의 및 대표값(유효/무효) 도출
age_valid = [0, 35, 120]
age_invalid = [-1, 121, None]
sort_valid = ["asc", "desc"]
sort_invalid = ["", "up"]
q_valid = ["phone", "laptop"]
q_invalid = ["", " "]
# 2) 데이터 세트 구성
valid_sets = [age_valid, sort_valid, q_valid]
invalid_sets = [age_invalid, sort_invalid, q_invalid]
# 3) 유효 조합 생성
def make_cartesian(params):
for combo in product(*params):
yield {"age": combo[0], "sort": combo[1], "q": combo[2]}
def make_pairwise(params):
for combo in AllPairs(params):
yield {"age": combo[0], "sort": combo[1], "q": combo[2]}
valid_cases = list(make_pairwise(valid_sets)) if PAIRWISE_AVAILABLE else list(make_cartesian(valid_sets))
# 4) 무효 단일치 테스트(음수 테스트)
invalid_cases = []
for i, param in enumerate(invalid_sets):
for v in param:
base = [age_valid[1], sort_valid[0], q_valid[0]] # 안정적 기준
base[i] = v
invalid_cases.append({"age": base[0], "sort": base[1], "q": base[2]})
print(f"유효 케이스 수: {len(valid_cases)} / 무효 케이스 수: {len(invalid_cases)}")
# 오라클 예: 유효 -> HTTP 200, 무효 -> HTTP 400 및 에러 코드 검증
큰 입력 공간에서는 페어와이즈 이상(t-wise) 적용과 금지 조합 필터가 필요하다. 무효 케이스는 상태 변화가 없는지, 에러 메시지가 표준화됐는지, 로깅과 모니터링이 연계되는지를 확인한다.
케이스 수를 줄이면서 추적성을 남기기
각 입력 축의 원소 수를 n이라 할 때, 기존 조합은 O(∏n)이고 동등 분할 적용 후에는 O(∏k)로 다룬다. k는 클래스 수이며 일반적으로 n 대비 60~90% 감소한다.
예를 들어 5개 파라미터에 각 10값이 있으면 10^5=100,000개 조합이 된다. 각 파라미터를 3클래스(유효 1~2, 무효 1)로 가정하면 3^5=243이고, 페어와이즈를 적용하면 2540개 수준이다.
케이스 수 감소와 함께 테스트 일관성, 요구사항-테스트 추적, 음수 시나리오의 품질을 높일 수 있다. 규칙이 바뀌었을 때 영향 범위도 명확해지고 자동화 파이프라인에 적용하기 쉬워진다.
규칙과 클래스의 균형
동등 분할은 입력 도메인을 규칙 기반으로 나누고 대표값을 검증해 적은 케이스로 넓은 범위를 다루는 방법이다. 경계값 분석으로 경계 취약점을 보완하고, 페어와이즈로 다변수 조합의 규모를 제어할 수 있다. 요구사항에서 규칙을 추출해 정식화하고 유효·무효 클래스를 균형 있게 설계하는 일이 이 기법의 중심이다.