의사결정테이블로 비즈니스 규칙 테스트 설계하기

의사결정테이블의 조건·행위 매핑, 규칙 축소, 충돌·누락 검증을 통해 복잡한 비즈니스 규칙의 테스트 케이스를 설계하는 방법

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

조건 조합을 규칙으로 고정하는 방법

비즈니스 규칙이 복잡해질수록 조건 조합 사이의 누락, 충돌, 모호성이 늘어난다. 의사결정테이블(Decision Table)은 조건과 행위를 표로 대응시켜 가능한 조합을 규칙(Rule) 단위로 관리하는 테스트 설계·검증 기법이다. 요건을 해석하고 규칙을 문서화하며 테스트 케이스를 전개하는 작업을 하나의 구조 안에 묶는다.

테이블은 조건(Condition)과 행위(Action)를 축으로 삼는다. 각 규칙 컬럼에는 조건 엔트리의 조합과 그 조합에서 기대하는 행위 엔트리가 함께 들어간다. 조건은 보통 True/False로 표시하지만, 범주형 조건이나 Don't-care(-)도 사용할 수 있다. 표는 조건 스텁, 조건 엔트리, 행위 스텁, 행위 엔트리의 4구역으로 구성한다.

이 방식은 다음 가정 위에서 동작한다.

  • 조건의 순서를 바꿔도 행위 결정에는 영향이 없다.
  • 행위는 조건이 트리거가 되어 결정된다.
  • 행위는 조건 조합에 의해서만 영향을 받으며 외생 변수의 영향은 없다.

규칙을 전개하고 검증하는 기준

먼저 각 조건의 도메인 곱집합으로 규칙 후보 수를 계산하고 진리표를 만든다. 이후 불가능하거나 불필요한 조합을 제약식으로 제외하고, 중복과 모순을 검토한다. 이해관계자 리뷰는 누락된 규칙을 보완하고 충돌을 해소하는 단계다.

조건 스텁과 행위 스텁은 규칙의 범위를 분명히 한다. 하나의 규칙은 조건 엔트리 조합과 이에 대응하는 행위 엔트리로 완결되며, T/F/-(Don’t-care) 표기를 일관되게 사용해야 해석이 흔들리지 않는다.

규칙 수는 Don't-care 병합, 동치 규칙 통합, 조건 분해·통합으로 줄일 수 있다. 위험 기반 우선순위와 경계·예외 조합을 강조하고, Pairwise나 MC/DC를 함께 적용할 수도 있다. 목표는 커버리지를 보존하면서 테스트 케이스 수를 최소화하는 데 있다.

요구사항→규칙→테스트케이스의 양방향 추적성을 갖추면 변경 시 영향을 받는 규칙을 한정할 수 있다. 동일 조건 조합에 두 규칙이 서로 다른 행위를 지정하는 결정 모호성과, 어떤 규칙도 대응하지 않는 결정 없음을 자동으로 검출할 수 있다.

할인 정책부터 접근제어까지

가격·할인 엔진에서는 등급, 시즌, 쿠폰, 결제수단처럼 여러 조건을 조합해 할인 정책을 정한다. 결제 경로별 예외 규칙을 병합하면 케이스 수를 50% 이상 줄이는 사례가 빈발한다.

여신·보험 인수 심사에는 소득, 신용점수, 부채비율, 연체이력처럼 이진 조건과 범주 조건이 섞인다. 같은 조합에 서로 다른 결정이 배정된 규칙 충돌을 찾아 승인 오류를 사전에 차단할 수 있다.

접근제어와 Feature Toggle에서는 역할, 조직, 리전, 위험도를 조합해 허용·차단·추가 인증을 결정한다. 릴리스 전에 규칙을 검증하면 접근 예외 발생률을 낮출 수 있다.

대출 승인 규칙을 축소한 예

조건은 다음과 같이 둔다.

  • C1: 소득 ≥ 임계값 (T/F)
  • C2: 신용점수 ≥ 임계값 (T/F)
  • C3: 부채비율 ≤ 임계값 (T/F)

행위는 A1: 즉시 승인, A2: 추가 서류 요청, A3: 거절이다. 규칙은 다음과 같이 표현할 수 있다.

  • R1: C1=T, C2=T, C3=T → A1
  • R2: C1=T, C2=T, C3=F → A2
  • R3: C1=T, C2=F, C3=- → A2
  • R4: C1=F, C2=-, C3=- → A3

R3과 R4에는 Don't-care를 적용했다. 총 8조합을 4규칙으로 줄인 형태이며, 조건 순서 불변성, 규칙 충돌 부재, 규칙 누락 부재를 검증해야 한다.

정규화 진행진리표 생성제약 적용매핑/검증충돌 발견누락 발견정상테스트 실행수정 재검증보완 재검증요구사항/규칙 수집조건 정규화 중복/의존성분석조합 생성(진리표)불가능 조합 제거'Don't-care' 병합행위 매핑 충돌/누락 검증오류: 규칙 충돌 또는 모호성오류: 불완전 규칙(누락)테스트 케이스 산출 우선순위실행/결과 분석 회귀 세트업데이트

누락을 줄이고 회귀 범위를 좁히는 효과

규칙 누락과 충돌을 일찍 찾으면 요구사항 결함 발견률을 20~35%p 개선할 수 있다. 예를 들어 6개 이진 조건은 이론상 2^6=64조합이지만, 제약과 병합을 적용한 뒤 18규칙으로 축소하고 누락 0건을 목표로 할 수 있다.

Don't-care 병합과 동치 규칙 통합은 테스트 케이스를 40~70% 줄일 수 있다. 여기에 위험 기반 우선순위를 적용하면 고위험 조합부터 검증할 수 있다.

규칙 변경의 영향 범위를 특정하고 회귀 세트를 자동 갱신할 수 있다는 점도 유지보수에 유리하다. 요구사항–규칙–케이스 추적성은 변경 리드타임을 단축하며, 예시로 30% 내외의 단축이 제시된다.

입력에서 테스트 케이스까지의 흐름

입력으로는 비즈니스 규칙, 용어사전, 제약식, 예외 목록을 준비한다.

조건 정규화 단계에서는 도메인을 분해해 이진화하고, 상호배타·포함 관계를 명시한다. 조합은 전수 방식 또는 Pairwise/MC/DC 전략으로 생성한다. 이후 제약 기반 필터, Don't-care 병합, 동치 규칙 통합으로 축소한다.

검증에서는 동일 조합이 상이한 행위에 연결되는 충돌, 행위가 매핑되지 않은 조합의 누락, 하나의 조합이 하나의 규칙으로 결정되는지를 확인한다. 결과물은 최종 의사결정테이블, 우선순위가 부여된 테스트 케이스, 추적 매트릭스다.

모호성을 발견하면 규칙을 재정의하고 조건 분해를 다시 설계한다. 누락이 드러나면 요구사항을 명확히 하고 기본 규칙(Default)을 합의한다.

파이썬으로 조합과 누락을 확인하기

전제조건은 Python 3.10+ 환경이며 외부 라이브러리는 필요하지 않다.

from itertools import product

# 1) 조건 정의(T/F), 제약식, 행위 매핑 규칙
conditions = ["C1_income", "C2_credit", "C3_debt"]  # 이진 조건
domain = {c: [True, False] for c in conditions}

def constraint(assign: dict) -> bool:
    # 불가능 조합 제거 규칙(예시): 없음 → 모두 허용
    return True

def action_mapping(assign: dict) -> str | None:
    C1, C2, C3 = assign["C1_income"], assign["C2_credit"], assign["C3_debt"]
    # 규칙 R1~R4
    if C1 and C2 and C3: return "A1_approve"
    if C1 and C2 and not C3: return "A2_docs"
    if C1 and not C2: return "A2_docs"     # C3는 Don’t-care
    if not C1: return "A3_reject"          # C2,C3는 Don’t-care
    return None  # 누락 탐지용

# 2) 조합 생성 및 필터
all_assign = [
    dict(zip(conditions, vals))
    for vals in product(*(domain[c] for c in conditions))
]
valid_assign = [a for a in all_assign if constraint(a)]

# 3) 행위 매핑 및 검증
cases, missing = [], []
for a in valid_assign:
    act = action_mapping(a)
    if act is None:
        missing.append(a)
    else:
        cases.append((a, act))

# 4) 중복 행위 병합(동일 행위로 귀결되는 조합 그룹화)
from collections import defaultdict
groups = defaultdict(list)
for a, act in cases:
    groups[act].append(a)

print("총 조합:", len(all_assign))
print("유효 조합:", len(valid_assign))
print("누락 조합 수:", len(missing))
for act, assigns in groups.items():
    print(act, "→", len(assigns), "case(s)")

action_mappingNone을 반환하면 누락 규칙이 있다는 뜻이다. 여러 규칙이 같은 조합을 포착하면 충돌 가능성이 있다. groups를 규칙 수준으로 환원하면 Don't-care를 적용할 기회를 찾을 수 있다.

요구사항 변경이 잦은 도메인에서는 의사결정테이블을 먼저 적용할 만하다. 제약을 반영하고 Don't-care를 병합한 규칙을 자동화와 연결하면, 커버리지를 유지하면서 테스트 비용을 줄일 수 있다.

의사결정테이블테스트 설계비즈니스 규칙조합 테스트품질 관리