개념
모듈 1(레슨 5, "완전한 테스트는 불가능하다")에서 필드 몇 개짜리 폼도 조합이 수백 가지로 폭발한다는 걸 계산으로 확인했다. 페어와이즈는 이 문제를 실무에서 다룰 수 있는 크기로 줄이는 구체적인 방법이다.
이 레슨은 세 가지를 순서대로 다룬다 — 조합 폭발이 실제로 얼마나 심각한지 숫자로 확인하고, 그것을 줄이는 경험칙이 어디서 나왔고 어디까지 믿을 수 있는지 따져보고, 도구(PICT)로 실제 테스트 케이스를 뽑아내는 흐름을 끝까지 따라간다.
조합 폭발은 실제로 얼마나 심각한가
말로 하면 실감이 안 난다. 실제 서비스에 있을 법한 파라미터로 직접 세어보자. 어떤 쇼핑몰의 상품 상세 화면을 테스트한다고 하자.
| 파라미터 | 값 | 값 개수 |
|---|---|---|
| 브라우저 | Chrome, Safari, Firefox, Edge | 4 |
| OS | Windows, macOS, iOS | 3 |
| 화면 크기 | 데스크톱, 태블릿, 모바일 | 3 |
| 언어 | 한국어, 영어 | 2 |
| 회원등급 | 비회원, 일반, VIP | 3 |
전수조합은 곱셈이다 — 4 × 3 × 3 × 2 × 3 = 216가지. 파라미터를 하나씩 더해갈 때 숫자가 어떻게 움직이는지 보면 감이 온다.
| 지금까지 포함한 파라미터 | 누적 전수조합 |
|---|---|
| 브라우저만 | 4 |
| + OS | 12 |
| + 화면 크기 | 36 |
| + 언어 | 72 |
| + 회원등급 | 216 |
파라미터가 하나 늘 때마다 케이스는 덧셈이 아니라 곱셈으로 늘어난다. 이게 "조합 폭발"이라는 말의 정확한 의미다. 여기에 파라미터 하나만 더 붙여보자 — 결제수단 4가지(카드/계좌이체/간편결제/포인트)를 넣으면 216 × 4 = 864가지가 된다. 파라미터 하나를 추가했을 뿐인데 케이스가 648건 늘었다.
시간으로 환산하면 더 분명해진다. 한 케이스를 실행하고 결과를 기록하는 데 15분이 걸린다고 하자.
| 범위 | 케이스 수 | 소요 시간 | 실제 근무일 (하루 6시간 실작업) |
|---|---|---|---|
| 전수조합 (5개 파라미터) | 216 | 54시간 | 9일 |
| 전수조합 (결제수단 추가) | 864 | 216시간 | 36일 |
| 페어와이즈 (5개 파라미터) | 약 14 | 3.5시간 | 반나절 |
36일짜리 회귀 테스트는 스프린트 안에 들어가지 않는다. 그래서 현실에서는 대개 아무 근거 없이 "적당히 몇 개만" 골라서 테스트하게 되는데, 이건 줄이는 게 아니라 무엇을 안 봤는지 모르는 상태 가 되는 것이다. 페어와이즈는 바로 이 지점을 대체한다.
페어와이즈로 줄이면 몇 건이 되는가 — 직접 세어보기
페어와이즈의 목표는 "모든 조합"이 아니라 "모든 두 파라미터의 값 쌍(pair)" 을 최소 한 번씩 덮는 것이다. 그럼 덮어야 할 쌍이 몇 개인지부터 세어보자.
| 파라미터 쌍 | 값 조합 수 |
|---|---|
| 브라우저 × OS | 4 × 3 = 12 |
| 브라우저 × 화면 크기 | 4 × 3 = 12 |
| 브라우저 × 언어 | 4 × 2 = 8 |
| 브라우저 × 회원등급 | 4 × 3 = 12 |
| OS × 화면 크기 | 3 × 3 = 9 |
| OS × 언어 | 3 × 2 = 6 |
| OS × 회원등급 | 3 × 3 = 9 |
| 화면 크기 × 언어 | 3 × 2 = 6 |
| 화면 크기 × 회원등급 | 3 × 3 = 9 |
| 언어 × 회원등급 | 2 × 3 = 6 |
| 합계 | 89쌍 |
여기서 핵심은 테스트 케이스 한 건이 여러 쌍을 동시에 덮는다 는 점이다.
파라미터가 5개면 한 케이스에서 만들어지는 쌍의 개수는 5개 중 2개를 고르는
경우의 수, 즉 10개다. 예를 들어 Chrome / Windows / 데스크톱 / 한국어 / VIP
라는 한 건은 Chrome×Windows, Chrome×데스크톱, Windows×VIP 등 10개의
쌍을 한꺼번에 처리한다.
그래서 이론적인 하한은 두 가지 방향에서 나온다.
- 쌍의 총량 기준: 89쌍 ÷ 한 건당 10쌍 = 최소 9건
- 가장 큰 곱 기준: 브라우저(4) × OS(3) = 12가지 쌍은 절대 겹칠 수 없으므로 최소 12건
둘 중 큰 쪽이 실제 하한이므로 최소 12건 이고, 알고리즘이 완벽하지 않으니 실제 도구는 보통 13~15건 을 만들어낸다. 216건이 14건이 된다 — 약 6.5% 로 줄었는데, 파라미터 두 개짜리 조합은 89개가 전부 검증된다.
왜 이게 말이 되는가 — 한 자리에서 여러 명을 만나기
숫자만 보면 마술 같지만, 원리는 단순하다. 회사 5곳에서 온 사람들이 참석한 모임을 떠올려보자. "모든 회사의 사람이 다른 모든 회사의 사람과 최소 한 번씩 인사한다"가 목표라면, 한 명씩 일대일로 돌아다니는 것보다 한 테이블에 회사별로 한 명씩 앉히는 것 이 훨씬 빠르다. 5명이 한 테이블에 앉으면 그 자리에서 10쌍이 동시에 인사한다.
테스트 케이스 한 건이 정확히 이 "테이블"이다. 페어와이즈 알고리즘이 하는 일은 남은 쌍을 가장 많이 덮는 테이블 배치를 계속 찾아내는 것 이다. 그래서 89쌍을 14번의 테이블만으로 다 처리할 수 있다.
경험칙의 근거 — NIST의 상호작용 결함 연구
"결함 대부분은 두 값의 조합에서 나온다"는 말은 실무 감각으로만 떠도는 이야기가 아니다. 미국 국립표준기술연구소(NIST)의 Rick Kuhn 연구팀은 여러 실제 시스템의 결함 데이터베이스를 뒤져 "이 결함을 재현하려면 몇 개의 파라미터가 특정 값으로 동시에 맞아야 했는가" 를 하나하나 분류했다. 조사 대상은 의료기기, 웹 브라우저, HTTP 서버, NASA의 분산 데이터베이스 등이었다.
결과를 누적 비율로 정리하면 대략 이런 모양이다(NIST SP 800-142 등에 실린 값을 반올림한 것이다).
| 시스템 | 1개 값만으로 | 2개까지 누적 | 3개까지 누적 | 4개까지 누적 |
|---|---|---|---|---|
| 의료기기 | 약 66% | 약 97% | 약 99% | 100% |
| 웹 브라우저 | 약 29% | 약 76% | 약 95% | 약 99% |
| HTTP 서버 | 약 42% | 약 70% | 약 89% | 약 96% |
| NASA 분산 DB | 약 68% | 약 93% | 약 98% | 100% |
여기서 두 가지를 읽어야 한다.
첫째, 곡선이 가파르게 올라갔다가 금방 눕는다. 파라미터 2개까지만 봐도 대부분의 결함이 걸리고, 3개를 넘어가면 추가로 얻는 게 급격히 줄어든다. 이 "수확 체감" 이 페어와이즈가 실용적인 이유다.
둘째, 어떤 시스템에서도 6개를 넘는 상호작용은 발견되지 않았다. 연구팀은 이를 상호작용 규칙(interaction rule) 이라 불렀다. 결함을 촉발하는 데 필요한 파라미터 수에는 사실상 상한이 있다는 뜻이다.
다만 이 데이터를 인용할 때 반드시 붙여야 하는 단서가 세 가지 있다. 면접이나 리뷰에서 이 단서까지 말할 수 있으면 수준이 달라 보인다.
- "몇 %를 잡는다"가 아니라 "몇 %가 그 정도 상호작용으로 촉발됐다"이다. 2-way 커버리지를 달성해도, 그 결함이 걸리려면 해당 조합이 실행됐을 때 테스트 오라클(기대 결과 판정)이 이상을 알아채야 한다. 화면을 열어만 보고 숫자를 확인하지 않으면 조합을 실행하고도 결함을 지나친다.
- 조사된 시스템 몇 개의 결과이지 소프트웨어 전체의 통계가 아니다. 도메인에 따라 곡선은 다르게 그려진다.
- "파라미터를 어떻게 나눴는가"에 따라 숫자가 바뀐다. 입력 모델을 잘못 만들면 이 통계와 아무 상관없는 결과가 나온다.
경험칙이 통하지 않는 곳 — 언제 3-wise 이상을 써야 하는가
표를 다시 보면 브라우저와 HTTP 서버는 2-way에서 각각 76%, 70%다. 나머지 20~30%는 세 개 이상이 동시에 맞아야만 재현되는 결함 이라는 뜻이다. 구체적으로 이런 모습이다.
게스트 결제 이면서 해외 발급 카드 이면서 3만원 미만 주문 일 때만 부가세 계산이 틀린다. 셋 중 하나라도 다르면 정상이다.
이 결함은 페어와이즈 스위트가 우연히 그 3중 조합을 포함하지 않는 한 통과된다. 그래서 리스크에 따라 커버리지 강도(t 값)를 다르게 잡는다.
| 영역 | 권장 강도 | 이유 |
|---|---|---|
| 화면 표시, 필터, 정렬 같은 UI 옵션 | 2-wise | 틀려도 되돌릴 수 있고, 결함 비용이 낮다 |
| 일반 업무 로직 | 2-wise + 중요 조합 수동 추가 | 대부분 여기에 해당한다 |
| 결제·정산·세금 계산 | 3-wise 이상 | 금액이 틀리면 되돌리는 비용이 매우 크다 |
| 권한·인증·보안 | 3-wise 이상 | "특정 조건 셋이 겹칠 때만 뚫린다"가 전형적인 취약점 형태다 |
| 생명·안전 관련 (의료·항공) | 4-wise 이상 또는 전수 | 규제가 요구하는 경우가 많다 |
강도를 올리면 케이스가 얼마나 늘어나는지도 미리 계산해두면 협상이 쉬워진다. 앞의 5개 파라미터 예에서 3-wise로 올리면, 가장 큰 세 파라미터의 곱인 브라우저(4) × OS(3) × 화면 크기(3) = 36건이 하한 이고 도구는 보통 40건 안팎을 만들어낸다.
| 강도 | 케이스 수 | 전수(216) 대비 |
|---|---|---|
| 2-wise | 약 14 | 6.5% |
| 3-wise | 약 40 | 18.5% |
| 전수 | 216 | 100% |
결제 로직에만 3-wise를 쓴다면 40건은 충분히 감당할 수 있는 숫자다. 전체를 3-wise로 올리는 게 아니라, 위험한 영역만 강도를 올리는 것 이 실무의 정답이다.
PICT 실제로 써보기 — 모델 파일부터 테스트 케이스까지
이 조합을 손으로 짜는 건 파라미터가 늘어날수록 어려워진다. PICT(Pairwise Independent Combinatorial Testing) 는 마이크로소프트가 만든 무료 명령줄 도구로, 파라미터와 값을 텍스트 파일로 적으면 조합을 자동으로 계산해준다. 비슷한 도구로 Allpairs, JENNY 도 있고 원리는 같다.
1단계 — 입력 모델 파일 작성
model.txt 같은 텍스트 파일에 파라미터: 값1, 값2, ... 형식으로 적는다.
브라우저: Chrome, Safari, Firefox, Edge
OS: Windows, macOS, iOS
화면크기: 데스크톱, 태블릿, 모바일
언어: 한국어, 영어
회원등급: 비회원, 일반, VIP이 파일이 이 레슨에서 가장 중요한 산출물 이다. 뒤에서 다시 말하겠지만, 결과의 품질은 전적으로 이 파일의 품질에서 나온다. 값을 어떻게 나눌지는 레슨 1에서 배운 동등분할 로 먼저 정리한 뒤 옮겨 적는다.
2단계 — 실행
pict model.txt > result.tsv결과는 탭으로 구분된 표로 나온다. 엑셀이나 스프레드시트에 그대로 붙여넣을 수
있다. 강도를 올리려면 /o 옵션을 쓴다.
pict model.txt /o:3 > result-3way.tsv3단계 — 제약조건(constraint) 넣기
여기가 실무에서 가장 중요한 부분이다. 위 모델을 그대로 돌리면
Chrome / iOS, Edge / macOS 같은 현실에 존재하지 않는 조합 이 나온다.
존재하지 않는 조합을 테스트 케이스로 만들면 실행 단계에서 "이건 못 해요"가
되어 버리고, 그만큼 커버리지에 구멍이 생긴다.
PICT는 IF ... THEN ... 형식으로 제약을 표현한다.
브라우저: Chrome, Safari, Firefox, Edge
OS: Windows, macOS, iOS
화면크기: 데스크톱, 태블릿, 모바일
언어: 한국어, 영어
회원등급: 비회원, 일반, VIP
IF [OS] = "iOS" THEN [브라우저] = "Safari";
IF [OS] = "iOS" THEN [화면크기] IN {"태블릿", "모바일"};
IF [브라우저] = "Edge" THEN [OS] = "Windows";
IF [회원등급] = "비회원" THEN [언어] = "한국어";읽는 법은 문장 그대로다 — "OS가 iOS이면 브라우저는 Safari만 가능하다."
제약을 넣으면 PICT는 제약을 지키면서 나머지 쌍을 최대한 덮는 조합만
만들어낸다. 불가능한 쌍(예: Chrome × iOS)은 커버 대상에서 자동으로 빠진다.
제약조건을 빼먹는 것이 PICT 입문자의 가장 흔한 실수다. 제약 없이 돌린 표를 그대로 테스트 케이스로 넘기면, 팀에서 "이 케이스는 실행이 안 되는데요" 라는 말이 돌아오고 표 전체의 신뢰가 무너진다.
4단계 — 중요한 조합 강제로 넣기, 자주 쓰는 조합에 무게 주기
두 가지 도구가 더 있다.
가중치(weight) — 값 뒤 괄호에 숫자를 적으면 그 값이 더 자주 등장한다. 실제 사용자 분포를 반영하고 싶을 때 쓴다.
브라우저: Chrome (10), Safari (3), Firefox (1), Edge (1)시드(seed) 파일 — 반드시 포함되어야 하는 조합을 미리 적어두면, PICT가 그 행들을 먼저 포함시킨 뒤 나머지 쌍을 채운다. 뒤에서 다룰 "비즈니스적으로 중요한 조합"을 보장하는 장치가 바로 이것이다.
pict model.txt /e:seed.txt > result.tsvseed.txt는 결과 표와 같은 형식(첫 줄에 파라미터 이름, 탭 구분)으로 쓴다.
5단계 — 조합표를 테스트 케이스로 옮기기
PICT가 내놓는 것은 입력 조합의 목록 이지 테스트 케이스가 아니다. 실행 가능한 케이스가 되려면 열을 세 개 더 붙여야 한다.
| # | 브라우저 | OS | 화면크기 | 언어 | 회원등급 | 사전조건 | 실행 절차 | 기대 결과 |
|---|---|---|---|---|---|---|---|---|
| 1 | Chrome | Windows | 데스크톱 | 한국어 | VIP | VIP 계정 로그인 | 상품 상세 진입 | VIP 전용가 표시, 레이아웃 정상 |
| 2 | Safari | iOS | 모바일 | 영어 | 일반 | 일반 계정 로그인 | 상품 상세 진입 | 영문 표기, 정가 표시 |
| 3 | Firefox | macOS | 태블릿 | 한국어 | 비회원 | 로그아웃 상태 | 상품 상세 진입 | 로그인 유도 배너 노출 |
기대 결과 열이 조합마다 달라진다는 점 을 눈여겨보자. 회원등급이 바뀌면 기대하는 가격 표시가 달라진다. 이 열을 채우는 순간 "실행은 했는데 뭘 봐야 하는지 몰랐다"는 상황이 사라진다 — 앞에서 말한 오라클 문제 를 여기서 해결하는 것이다. 도구는 왼쪽 다섯 열까지만 만들어주고, 오른쪽 세 열은 QA의 일이다.
페어와이즈가 만능이 아닌 이유
페어와이즈는 "89쌍 중 89쌍 커버, 100%"처럼 숫자로 된 근거 를 주기 때문에 설득력이 강하다. 바로 그래서 위험하다. 숫자가 높다는 것과 충분하다는 것은 다른 이야기다. 네 가지를 조심한다.
첫째, 커버리지 100%는 "쌍" 기준의 100%다. 3중·4중 조합에 대해서는 아무 말도 하지 않는다. 앞의 부가세 사례처럼 세 조건이 겹쳐야 터지는 결함은 2-wise 100% 스위트를 그대로 통과한다. 보고할 때는 "조합 커버리지 100%"가 아니라 "2-way 조합 커버리지 100%" 라고 t 값을 반드시 붙여 말한다.
둘째, 비즈니스적으로 중요한 조합이 우연히 빠질 수 있다. 알고리즘은 쌍을
효율적으로 덮는 것만 생각할 뿐, VIP 회원 × 간편결제가 매출의 40%를 차지하는
조합이라는 사실을 모른다. 그 쌍 자체는 어딘가에서 한 번 등장하겠지만,
하필 Firefox / 태블릿 / 영어 같은 실사용자가 거의 없는 환경과 묶여서 나올
수 있다. 그래서 실무에서는 순서를 이렇게 잡는다.
- 도구를 돌리기 전에 "이건 반드시 봐야 한다"는 조합을 먼저 손으로 적는다 (매출 상위 조합, 최근 장애가 났던 조합, 신규 기능과 기존 기능이 만나는 조합).
- 그 목록을 시드 파일(
/e:)로 넣어 강제로 포함 시킨다. - 나머지를 페어와이즈로 채운다.
이렇게 하면 "중요한 건 다 들어갔고, 나머지는 근거 있게 줄였다"는 두 가지를 동시에 말할 수 있다.
셋째, 입력 모델이 틀리면 결과도 틀린다. 값을 어떻게 나눴는지가 결과를
전부 결정한다. "금액"을 1000원 / 50000원 두 값으로 나눈 모델과
0원 / 29999원 / 30000원 / 30001원으로 나눈 모델은 완전히 다른 스위트를
만든다. 경계값이 값 목록에 들어 있지 않으면 페어와이즈는 절대로 경계값을
테스트하지 않는다. 레슨 1의 동등분할·경계값 분석이 페어와이즈의 앞 단계
인 이유다.
넷째, 결과를 이해하지 못한 채 쓰면 리뷰에서 방어할 수 없다. "PICT가 만들어줬습니다"는 근거가 아니다. "파라미터 5개, 값 조합 89쌍을 14건으로 전부 덮었고, 결제 관련 3개 파라미터는 별도로 3-wise를 돌렸습니다"가 근거다.
다른 설계 기법과의 자리
이 모듈에서 배우는 기법들이 서로 어떻게 맞물리는지 정리해두자.
| 기법 | 다루는 문제 | 페어와이즈와의 관계 |
|---|---|---|
| 동등분할·경계값 (레슨 1) | 값 하나의 범위를 어떻게 자를까 | 앞 단계 — 페어와이즈에 넣을 값 목록을 만든다 |
| 결정 테이블 (레슨 3) | 조건 조합마다 결과가 다를 때 | 조건이 적고 규칙이 명확하면 이쪽. 조건이 많아 표가 감당 안 되면 페어와이즈 |
| 분류 트리 (레슨 6) | 파라미터와 값을 구조적으로 정리 | 입력 모델을 그림으로 만드는 방법. 그 결과를 페어와이즈에 넣는다 |
| 구조 기반 기법 (레슨 7) | 코드의 분기를 다 밟았는가 | 관점이 다르다. 명세 기반과 함께 쓴다 |
핵심 판단 기준은 이렇다. "어떤 조합에서 무슨 일이 일어나야 하는지 명세가 말해주고 있다"면 결정 테이블 이고, "특별히 의심되는 조합은 없지만 파라미터가 많아 다 볼 수 없다"면 페어와이즈 다. 결정 테이블은 규칙을 검증하고, 페어와이즈는 범위를 확보한다.
실무에서 왜 필요한가
설정 화면, 필터 옵션, 결제 수단, 브라우저 지원 매트릭스처럼 파라미터가 많은 영역 에서 페어와이즈는 현실적인 테스트 범위를 만드는 거의 유일한 방법이다. 전수 테스트는 시간상 불가능하고, 그렇다고 아무렇게나 몇 개만 골라 테스트하면 "왜 이 케이스들을 골랐는지" 설명할 수 없다(모듈 1, 레슨 5에서 강조한 부분). 페어와이즈는 "왜 14개인가"에 대해 "모든 두 파라미터 조합 89쌍을 커버하기 때문"이라는 명확한 근거를 제공한다.
구체적으로 실무에서 만드는 차이는 네 가지다.
첫째, 테스트 범위 협상이 가능해진다. "시간이 없으니 좀 줄여주세요"라는 요청에 대해, 근거 없이 줄이는 대신 "2-wise로는 14건이고, 결제 부분만 3-wise로 올리면 30건입니다. 어느 쪽으로 할까요?"라고 선택지를 숫자로 제시 할 수 있다. 이건 QA가 일정 논의에서 발언권을 갖는 가장 실질적인 방법이다.
둘째, 회귀 테스트 스위트가 감당 가능한 크기로 유지된다. 기능이 추가될 때마다 케이스를 더하기만 하면 회귀 스위트는 몇 년 안에 아무도 다 돌리지 않는 문서가 된다. 파라미터 기반 영역을 페어와이즈로 재구성하면 크기를 붙잡을 수 있다.
셋째, 환경 매트릭스(브라우저·OS·기기)에 특히 잘 맞는다. 이 영역은 조합 수가 크면서 대부분의 조합이 서로 독립적이라, 페어와이즈가 가장 잘 듣는 전형적인 사례다. 스테이지 4에서 자동화를 배울 때 PICT 결과를 그대로 테스트 데이터 파일로 넘겨 파라미터화된 자동화 케이스를 만드는 방식으로 다시 만나게 된다.
넷째, 리뷰에서 방어할 수 있는 문서가 남는다. 입력 모델 파일(model.txt)은
그 자체로 "우리가 이 기능을 어떤 축으로 이해했는가" 의 기록이다. 릴리즈
후 결함이 났을 때 이 파일을 열어보면 "그 파라미터를 아예 모델에 넣지 않았다"는
사실이 즉시 드러난다. 이건 비난거리가 아니라 다음 회차에 모델을 고칠 근거다.
채용시장에서의 위치
조합 테스트는 ISTQB Foundation Level 명세 기반 기법 범위에 들어 있고, 경력 QA 면접에서는 "파라미터가 많은 화면을 어떻게 테스트하시겠어요?" 형태로 자주 나온다. 이 질문에서 면접관이 보는 것은 기법 이름을 아는지가 아니라 전수조합이 불가능하다는 것을 계산으로 인식하고 있는지, 그리고 줄인 근거를 설명할 수 있는지 다.
좋은 답의 구조는 이 레슨의 순서 그대로다 — "먼저 파라미터와 값을 동등분할로 정리해서 전수조합 수를 계산해봅니다. 수백 건이 나오면 PICT로 2-way 조합을 뽑고, 실행 불가능한 조합은 제약조건으로 걸러냅니다. 결제처럼 위험한 영역은 3-wise로 따로 돌리고, 매출 상위 조합은 시드로 강제 포함시킵니다."
여기에 "NIST 연구에서 2-way까지 누적 검출률이 70~97%였다"는 근거와, "다만 그건 결함이 촉발되는 상호작용 크기의 분포이지 검출을 보장하는 수치는 아니다"라는 단서를 함께 말할 수 있으면 확실히 구분된다. 후자를 말하는 지원자는 드물다.
도구 경험을 이력서에 쓸 때는 "PICT 사용"보다 "PICT 제약조건·시드 기반 조합 설계로 브라우저 매트릭스 회귀 케이스 200여 건을 15건으로 축소" 처럼 전후 숫자를 쓰는 편이 훨씬 잘 읽힌다.