원인-결과 그래프로 복잡한 분기 테스트 설계하기
원인과 결과의 불리언 관계 및 제약 조건을 그래프로 모델링하고, 의사결정표를 거쳐 실행 가능한 테스트케이스로 전환하는 방법
2026-08-14 · 최초 발행 2025-12-15
요구사항의 입력 조건과 결과를 논리식으로 연결하면, 복잡한 분기 규칙도 테스트 가능한 형태로 정리할 수 있다. 원인-결과 그래프 테스트는 불리언 연산과 제약 조건을 이용해 가능한 조합을 추려내고, 이를 의사결정표와 테스트케이스로 이어 붙이는 설계 기법이다.
명세의 모호성을 줄이고 커버리지를 관리해야 하는 인증, 결제, 제어 로직처럼 분기가 많은 영역에서 특히 유용하다.
원인과 결과를 논리 모델로 연결하는 방식
원인(Cause)은 입력 조건, 사건, 상태처럼 독립 변수에 해당한다. 결과(Effect)는 출력 조건, 시스템 액션, 상태 변화처럼 원인에 따라 달라지는 종속 변수다.
그래프에서는 원인과 결과에 C1, C2, E1, E2처럼 고유 식별자를 부여하고, AND·OR·NOT으로 복합 조건을 표현한다. 여기에 현실적으로 허용되지 않는 조합이나 우선순위를 제약으로 추가한다.
E(Exclusive): 상호 배타I(Inclusive): 동시 허용O(One and only one): 정확히 하나만 선택R(Requires): 선행 조건 요구M(Mask): 우선순위에 따라 하위 결과 무시
완성한 그래프는 원인과 결과를 행으로, 가능한 규칙을 열로 갖는 의사결정표로 변환한다. 각 열은 실행 가능한 테스트케이스 하나가 된다.
제약과 추적성을 함께 관리한다
그래프 모델에서는 불리언 식만 다루는 것이 아니다. 배타성, 선행 조건, 마스킹을 명시하면 비현실적인 조합을 제거하고 규칙 사이의 충돌도 일찍 발견할 수 있다.
의사결정표로 전환한 뒤에는 요구사항에서 그래프, 표의 열, 테스트케이스까지 연결된다. 이 연결을 유지하면 요구사항 변경 시 그래프와 결정표를 다시 만들면서 영향 범위를 확인할 수 있다.
효과(Effect) 커버리지, 규칙 커버리지, MC/DC 같은 기준을 적용할 수 있으며, 마스킹과 배타 제약을 이용해 중복 열을 줄여 최소 테스트 세트를 구성할 수 있다. Jira/Confluence, UML 도구, 스프레드시트 같은 요구사항 관리·모델링 도구와도 연계하기 쉽다.
그래프에서 테스트케이스까지 이어지는 흐름
먼저 입력 조건과 출력·액션·상태를 목록화하고 각각에 Ci, Ej 식별자를 붙인다. 이후 각 결과를 원인의 AND·OR·NOT 조합으로 표현하고, 복잡한 규칙은 중간 노드로 나눈다.
그 다음 배타(E), 정확히 하나(O), 선행(R), 마스킹(M) 등의 제약을 표시해 불가능한 조합을 제거한다. 그래프의 원인과 결과를 행으로 옮기고, 가능한 논리 조합을 열로 구성하면 의사결정표가 된다. 제약을 위반한 열은 삭제하거나 보정한다.
마지막으로 각 열에 입력값, 사전조건, 예상 결과를 채워 테스트케이스로 전환한다. 커버리지 기준을 확인한 뒤 필요한 열을 추가하거나 병합한다.
결제 승인 규칙을 그래프로 모델링한 예
결제 승인 로직을 다음 원인과 결과로 둔다.
-
원인(Cause)
- C1: 카드 유효
- C2: 한도 내 금액
- C3: 사기탐지 의심
- C4: 오프라인 모드
-
결과(Effect)
- E1: 승인
- E2: OTP 추가인증
- E3: 거절
결과 규칙은 다음과 같이 표현한다.
- E1 = C1 AND C2 AND NOT C3 AND NOT C4
- E2 = C1 AND C2 AND C3 AND NOT C4
- E3 = NOT C1 OR NOT C2 OR C4
여기에는 다음 제약이 붙는다.
- R: C2 → C1 (한도 검사는 유효 카드에만 적용)
- E: C3, C4 상호 배타(오프라인에서 사기탐지 불가)
- O: E1, E2, E3 중 정확히 하나 선택
- M: E3가 E1, E2를 마스킹(거절 우선)
그래프 규칙을 의사결정표로 옮기기
표기에서 Y는 예, N은 아니오, -는 해당 없음 또는 무시, X는 제약 위반으로 삭제할 조합이다.
| 조건/결과 | TC1(정상 승인) | TC2(OTP) | TC3(유효성 실패) | TC4(한도 초과) | TC5(오프라인) | TCX(삭제) |
|---|---|---|---|---|---|---|
| C1 카드 유효 | Y | Y | N | Y | Y | Y |
| C2 한도 내 | Y | Y | - | N | Y | Y |
| C3 사기 의심 | N | Y | - | - | - | Y |
| C4 오프라인 | N | N | N | N | Y | Y |
| — | — | — | — | — | — | — |
| E1 승인 | Y | N | N | N | N | N |
| E2 OTP | N | Y | N | N | N | N |
| E3 거절 | N | N | Y | Y | Y | Y |
| 비고 | 채택 | 채택 | 채택 | 채택 | 채택 | C3∧C4=E 위반 |
TCX처럼 제약을 위반한 열은 제거한다. 남은 열마다 입력 데이터, 사전조건, 예상 결과를 구체화하면 테스트케이스가 된다.
모든 결과인 E1~E3가 최소 1회 이상 발생하도록 커버리지를 확인한다. E3가 참인 조합은 E1/E2 테스트 목적에 맞지 않으므로, 마스킹(M)을 고려해 분리 설계한다. MUMCUT, MC/DC 같은 고급 기법을 적용하면 조합 수 감소와 결함 검출력 사이의 균형도 조정할 수 있다.
분기 규칙이 많은 시스템에서의 활용
인증과 결제에서는 로그인, 잠금, 2차 인증 분기를 모델링해 계정 보호 정책을 검증할 수 있다. 결제 승인·거절·추가인증 규칙과 사기탐지 연계 시나리오도 같은 방식으로 다룬다.
임베디드와 IoT 제어 로직에서는 센서 상태 조합과 액추에이터 동작의 배타·마스킹 관계를 표현한다. 안전 임계치 초과 시 페일세이프가 우선되는지도 검증 대상이 된다.
등급, 한도, 예외 규정을 다루는 정책·규정 엔진에서는 불리언 합성으로 규칙 충돌을 찾고, 의사결정표를 기반으로 회귀테스트를 자동화할 수 있다.
커버리지와 테스트 세트를 함께 다듬는 효과
규칙과 효과 커버리지 90%+ 달성이 가능하며, 누락 시나리오를 줄일 수 있다. 중복 조합을 제거하면 테스트케이스 수를 30~60% 절감할 수 있고, 배타·마스킹 충돌을 초기에 발견해 결함 유입을 차단하는 데도 도움이 된다.
요구사항이 바뀌었을 때 그래프와 의사결정표를 다시 생성하면 변경 영향 범위를 명확히 확인할 수 있다. 복잡한 분기 로직이 많은 시스템이라면, 논리 구조를 표준화하고 현실 가능한 조합만 추출하는 기본 테스트 설계 기법으로 적용할 만하다.