본문으로 건너뛰기
고급약 35분

모델 표기법과 모델 품질 — UML 상태기계·BPMN·결정 표

MBT 를 도입하면 유지보수 대상이 케이스 문서에서 모델로 옮겨간다. UML 상태기계·BPMN·결정 표가 각각 어떤 시스템에 맞는지 고르고, 도달 불가 상태·데드엔드·비결정 전이·가드 중복과 누락·추상화 수준이라는 기준으로 모델 자체를 리뷰하는 절차를 익힌다.

  • #모델기반테스트
  • #UML상태기계
  • #BPMN
  • #결정표
  • #모델품질

개념

유지보수 대상이 바뀌는 지점

모듈 3(레슨 11)에서 MBT 의 작동 원리를 봤다. 모델을 그래프로 만들고 도구가 순회해 경로를 뽑는다는 것, 그리고 그 대가로 빠뜨림이 모델 한 곳으로 모인다 는 것까지였다.

이 모듈은 그 "모델 한 곳" 을 운영하는 법을 다룬다. MBT 도입은 흔히 "케이스를 자동으로 만들어 준다" 로 요약되지만 체감되는 변화는 다른 쪽이다.

MBT 이전MBT 이후
정본(single source of truth)테스트 케이스 문서모델 파일
요구사항이 바뀌면 고치는 것영향받는 케이스를 찾아 하나씩모델의 정점·간선 몇 개
리뷰 대상케이스 목록모델, 그리고 생성 기준
품질이 무너지는 경로케이스가 서서히 낡는다모델이 틀리면 전부 틀린다

마지막 줄이 이 레슨의 존재 이유다. 케이스 문서는 100개 중 3개가 낡으면 3개만 낡는다. 모델은 한 군데가 틀리면 그 모델에서 생성된 케이스 전부가 같은 방향으로 틀리고, 그러고도 커버리지 리포트에는 100% 가 찍힌다. 그래서 MBT 를 쓰는 팀의 핵심 활동은 케이스 작성이 아니라 모델 리뷰 다. 이 레슨은 두 질문에 답한다 — 어떤 표기법으로 그릴지, 그리고 그린 모델이 쓸 만한지 어떻게 판정할지 다.

표기법 (1) UML 상태기계 — 시스템이 "어떤 상태에 있는가" 가 본질일 때

모듈 3(레슨 3)의 상태 전이표를 표준으로 정식화한 것이 UML 상태기계(State Machine Diagram)다. 구성 요소는 네 가지다.

요소MBT 에서의 역할
상태(state)그래프의 정점. 여기서 검증(assertion) 을 수행
전이(transition)그래프의 간선. 여기서 동작(action) 을 수행
가드(guard)참일 때만 그 간선이 선택 가능
액션(action)모델 변수를 갱신해 이후 가드를 좌우

표준 표기는 전이 하나를 이렇게 적는다.

결제대기 --[ 결제승인 / amount > 0 / paidAt = now() ]--> 결제완료
          └ 이벤트     └ 가드        └ 액션

가드와 액션이 있다는 점이 단순 상태 전이표와 결정적으로 다르다. 가드 덕분에 같은 이벤트가 조건에 따라 다른 상태로 갈라지고, 액션 덕분에 모델이 자체 변수를 들고 다닌다. 재고 수량·시도 횟수·잔액처럼 상태 이름으로 표현하면 폭발 하는 값을 모델 변수로 빼내는 것이 MBT 모델링의 기본 기술이다.

폭발을 막는 장치가 둘 더 있다. 계층 상태(composite state) 는 로그인됨 안에 둘러보기·장바구니·결제중 을 품어 "로그인됨이면 어디서든 로그아웃 가능" 을 전이 하나로 적게 해 준다. 직교 영역(orthogonal region) 은 독립적인 두 축을 곱집합으로 펼치지 않아 상태 수를 2 x 2 = 4 에서 2 + 2 로 줄인다.

다만 도구가 계층·직교를 지원하는지 반드시 확인해야 한다. 많은 MBT 생성기는 평탄한(flat) 그래프만 받는다. 그 경우 계층 모델은 사람이 읽는 산출물로 두고 생성기용 모델은 평탄화한 별도 파일로 유지하게 되는데, 그 둘이 어긋나는 것이 새로운 유지보수 문제 가 된다.

표기법 (2) BPMN — "누가 무엇을 하는 절차인가" 가 본질일 때

BPMN(Business Process Model and Notation)은 비즈니스 프로세스 표기 표준이다. 상태기계와 결정적으로 다른 점은 상태가 아니라 활동(activity)과 흐름을 그린다 는 것, 그리고 수행 주체(레인)와 참여자 간 메시지가 1급 요소 라는 것이다.

BPMN 요소테스트 설계에서 읽히는 것
태스크(task)한 사람·시스템이 하는 한 단위 작업. 테스트 스텝의 후보
배타 게이트웨이(XOR)조건 분기. 분기별로 최소 한 경로씩 필요
병렬 게이트웨이(AND)동시 진행. 순서가 정해지지 않은 조합 이 생긴다
레인(lane)·풀(pool)수행 주체. 역할별 권한 테스트의 근거
메시지 흐름시스템 경계를 넘는 호출. 인터페이스 테스트 지점
경계 이벤트(타이머·오류)타임아웃·예외 경로. 결함이 가장 많이 숨는 곳

전자결재·대출 심사·보험 청구·반품 처리처럼 여러 역할이 순서대로 개입하고 중간에 반송·보류·기한 초과가 끼어드는 업무가 BPMN 의 영역이다. 상태기계로 그리면 상태 이름이 업무 단계의 복제가 되고 "누가 하는가" 가 사라진다.

약한 곳도 있다. BPMN 자체는 "이 활동이 끝난 뒤 시스템이 어떤 상태인가" 를 말해 주지 않아 검증 지점을 사람이 붙여야 한다.

표기법 (3) 결정 표 — "조건 조합이 본질이고 순서는 없을 때"

모듈 3(레슨 3)의 결정 표는 가장 단순하면서 가장 과소평가된 모델이다. 상태도 흐름도 없고 조건의 조합과 그에 대한 결과만 있다.

조건1  회원 등급이 VIP 인가        Y  Y  N  N
조건2  주문 금액이 5만원 이상인가   Y  N  Y  N
---------------------------------------------
액션   무료배송 적용               O  O  O  X
액션   적립률                     5% 5% 2% 2%

보험료 산정, 요금제 적용, 권한 판정, 할인 정책처럼 "지금까지 무슨 일이 있었는지" 와 무관하게 현재 입력만으로 결과가 결정되는 로직이 결정 표의 영역이다. 상태기계로 그리면 상태가 조건 조합 수만큼 생긴다.

세 표기법을 고르는 기준

질문예 → 표기법
같은 입력인데 이전 이력에 따라 결과가 다른가?UML 상태기계
여러 역할이 순서대로 개입하고 반송·기한이 있는가?BPMN
현재 입력 조합만으로 결과가 정해지는가?결정 표
금지된 전이를 명시해야 하는가?상태기계 + 부정 전이

현실의 시스템은 대개 셋을 계층으로 섞어 쓴다.

BPMN            반품 업무 전체 절차 (접수 → 회수 → 검수 → 환불)
  └ 상태기계     반품 건 하나의 상태 (접수됨 → 회수중 → 검수중 → 환불완료 / 반송)
      └ 결정 표   "환불 금액 계산" 한 전이의 가드와 액션 (등급 x 사유 x 경과일)

상태기계는 전이·N-스위치 커버리지로 돌리고(레슨 2), 결정 표는 조합 기준으로 따로 돌린 뒤 가드 입력으로 공급한다. 한 모델에 전부 밀어넣지 않는 것이 모델 품질의 출발점이다.

모델 품질 — 테스트를 뽑기 전에 모델을 검사한다

아래 여섯 가지는 생성기를 돌리기 전에, 모델 파일만 보고 판정할 수 있다.

(1) 도달 불가 상태(unreachable state)

시작 상태에서 어떤 전이를 밟아도 닿을 수 없는 상태다. 그래프 탐색 한 번으로 찾는다. 원인은 둘 중 하나고 둘 다 보고할 거리다 — 진입 전이를 빠뜨린 모델 결함 이거나, 실제로 진입 경로가 없는 제품 쪽 죽은 상태 다. 방치하면 커버리지 분모가 채워지지 않아 100% 를 목표로 한 정지 조건이 끝나지 않는다(레슨 3).

(2) 데드엔드(dead end) / 싱크 상태

나가는 전이가 없는 상태다. 주문완료 처럼 의도된 종료 상태 인지, 결제실패 처럼 빠뜨린 복귀 전이 인지 구분해야 한다. 판정 기준은 하나다 — 실제 제품에서 사용자가 그 화면에 갇히는가. 갇히지 않는데 나가는 전이가 없으면 모델이 틀렸다. 의도되지 않은 데드엔드는 순회 생성기에 치명적이다. 무작위 순회가 거기 빠지면 경로가 그 자리에서 끊긴다.

(3) 비결정성(nondeterminism)

같은 상태에서 같은 이벤트로, 가드가 동시에 참이 되는 전이가 둘 이상 있는 경우다.

배송준비 --[ 취소요청 / 결제후 24시간 이내 ]--> 취소완료
배송준비 --[ 취소요청 / 출고지시 전 ]--------> 취소대기

두 가드는 동시에 참이 될 수 있다. 결제 10분 뒤에 출고지시 전이면 어느 전이를 타는가? 모델은 답하지 않는다. 생성기는 임의로 하나를 고르고, 그 결과 테스트가 어떤 날은 통과하고 어떤 날은 실패한다 — 플래키 테스트의 원인이 코드가 아니라 모델에 있는 경우다. 판정은 기계적으로 가능하다. 같은 출발 상태·같은 이벤트를 가진 전이들을 묶어 가드들이 서로 배타적인지 확인하고, 배타적이지 않으면 우선순위를 명시하거나 가드를 쪼갠다.

배송준비 --[ 취소요청 / 출고지시전 && 경과 ≤ 24h ]--> 취소완료
배송준비 --[ 취소요청 / 출고지시전 && 경과 > 24h ]--> 취소대기

(4) 가드의 중복과 누락

위 수정안이 보여 주는 두 성질에 이름을 붙인다. 결정 표의 완전성·무모순성 검사와 같은 개념이다.

성질질문위반하면
배타성(중복 없음)두 가드가 동시에 참이 될 수 있는가?비결정성 → 재현 불가 테스트
완전성(누락 없음)모든 입력 조합이 어떤 가드에도 걸리지 않을 수 있는가?침묵 실패 → 전이가 막혀 그 경로가 생성되지 않는다

누락이 더 위험하다. 중복은 테스트가 흔들려 눈에 띄지만, 누락은 그 전이가 조용히 선택되지 않아 커버리지 숫자만 조금 낮아진다. 그래서 모델 리뷰 양식에는 상태별로 가드 집합을 모아 "이 가드들의 논리합이 항상 참인가" 를 적는 칸 을 둔다.

(5) 추상화 수준의 일관성

한 모델 안에 사용자 관점 상태와 구현 관점 상태가 섞이면 생성된 경로를 실행 코드로 옮길 수 없다.

나쁜 모델:  장바구니 → 결제수단선택 → PG_API_호출중 → DB_트랜잭션_커밋 → 주문완료
좋은 모델:  장바구니 → 결제수단선택 → 결제진행중 → 주문완료

PG_API_호출중·DB_트랜잭션_커밋 은 테스트가 관찰할 수도, 그 상태로 직접 전이시킬 수도 없는 내부 단계다. 모델에 넣으면 전이는 늘어나는데 검증할 것이 없는 간선 이 생긴다. 판정 질문은 하나다 — 이 상태를 테스트 코드가 관찰할 수 있는가, 이 전이를 테스트 코드가 일으킬 수 있는가.

반대 방향의 오류도 있다. 사용중 하나로 뭉치면 전이 커버리지 100% 가 아무것도 말해 주지 않는다. 적정 수준의 기준은 "상태가 바뀌면 사용자가 할 수 있는 일이 바뀐다" 다 — 할 수 있는 일이 같으면 같은 상태다.

(6) 부정 전이의 명시 여부

모듈 3(레슨 3)의 상태-이벤트 매트릭스에서 빈칸이 전체의 80% 였던 것을 떠올리자. 모델에 화살표가 없으면 도구는 그 조합을 시도하지 않는다. 금지 전이를 테스트하려면 "이 전이는 거부되어야 한다" 는 간선을 명시적으로 넣는다.

배송완료 --[ 주문취소 / 항상 ]--> 배송완료   (액션: 400 응답과 상태 불변을 검증)

출발과 도착 상태가 같고 검증 내용이 "거부됨" 인 간선이다. 모델이 커지는 대신 빈칸의 존재가 모델 안에 기록되어, 리뷰에서 "이 조합은 왜 없나" 를 물을 수 있다.

나쁜 모델에서 나온 테스트는 많기만 하다

모델 결함생성 결과리포트에 보이는 모습
도달 불가 상태그 영역 케이스 0개커버리지 100% 가 영원히 안 나옴
데드엔드경로가 짧게 끊김케이스 수는 많은데 평균 길이가 짧음
비결정성같은 설정에서 다른 경로간헐적 실패. 코드를 들여다봐도 원인 없음
가드 누락그 전이가 선택되지 않음아무 증상 없음. 커버리지만 조금 낮음
과도하게 상세한 모델케이스 수 폭발"케이스 4,000개" — 검증 없는 간선이 대다수
과도하게 뭉친 모델케이스 소수전이 커버리지 100%, 결함 검출 0

MBT 도입 6개월 차 팀이 가장 흔히 맞는 상황이 마지막 둘이다. 케이스 수는 수동 시절의 10배인데 발견 결함은 늘지 않는다. 원인은 생성기가 아니라 모델이다.

실무에서 왜 필요한가

MBT 도입 제안이 거절되는 전형적인 이유는 "모델을 믿을 수 없다" 다. 이때 "모델을 잘 그리겠습니다" 는 답이 되지 않는다. "모델을 여섯 항목으로 정적 검사하고 그 결과를 리뷰 기록으로 남깁니다" 가 답이다. 도달 불가 상태·데드엔드· 비결정성은 사람의 판단 없이 그래프 탐색으로 찾히므로 이 검사는 CI 에 넣을 수 있다 — 모델 파일이 바뀔 때마다 돌아가는 린트가 된다.

표기법 선택도 실질적인 이득을 준다. 요금 정책을 상태기계로 그리려다 상태가 수십 개로 불어나 포기하는 일, 반품 업무를 상태기계로 그려 "누가 승인하는가" 가 모델에서 사라지는 일이 반복된다. "이 로직은 상태가 본질인가, 절차가 본질인가, 조건 조합이 본질인가" 를 먼저 묻는 습관이 그 몇 주를 아낀다.

가드의 완전성을 따지다 보면 "경과 24시간의 시작점이 결제 시각인가 승인 시각인가" 같은 질문이 나온다. 그건 명세의 공백 이다(레슨 4의 워크숍 절).

실습 과제

과제 1 — 표기법 고르고 근거 적기 (15분)

아래 다섯 기능에 UML 상태기계 / BPMN / 결정 표 중 하나를 배정하고, 고른 이유와 다른 표기법을 썼을 때 무엇이 망가지는지 를 한 줄로 적는다.

  1. 통신사 요금제 할인 적용 규칙 (결합 상품·가족 수·약정 기간)
  2. 휴가 신청 승인 (신청 → 팀장 → 인사 → 반송 가능, 기한 3일 초과 시 자동 상신)
  3. 전기차 충전기 세션 (대기 → 인증 → 충전중 → 일시정지 → 종료 → 정산)
  4. 로그인 시도 제한 (5회 실패 시 10분 잠금, 성공 시 카운터 초기화)
  5. 보험 청구 서류 완전성 판정 (서류 7종의 제출 여부 조합)

4번은 함정이다. 실패 횟수를 상태로 만드는 안과 모델 변수로 두는 안을 모두 그려 상태 수를 비교한다.

과제 2 — 모델 린트 돌리기 (25분)

아래 모델에서 여섯 기준에 해당하는 결함을 모두 찾아 결함 유형 / 해당 요소 / 왜 문제인가 / 수정안 네 칸의 표로 정리한다.

상태: 대기, 인증중, 충전중, 일시정지, 종료, 정산완료, 오류
 
T1  대기      --[ 카드태그 ]-------------------------> 인증중
T2  인증중    --[ 인증성공 ]-------------------------> 충전중
T3  인증중    --[ 인증실패 ]-------------------------> 오류
T4  충전중    --[ 일시정지요청 ]----------------------> 일시정지
T5  일시정지  --[ 재개요청 / 잔여시간 > 0 ]-----------> 충전중
T6  충전중    --[ 종료요청 ]-------------------------> 종료
T7  충전중    --[ 케이블분리 / 충전량 > 0 ]-----------> 종료
T8  충전중    --[ 케이블분리 ]-----------------------> 오류
T9  종료      --[ 정산성공 ]-------------------------> 정산완료
T10 정산완료  --[ 영수증발급 ]-----------------------> 정산완료

최소 다섯 건이 있다. 힌트 — 오류 상태, 일시정지 의 가드, T7 과 T8 을 함께 볼 것. 그리고 빈칸 중 반드시 거부되어야 하는 조합 하나를 고른다.

과제 3 — 추상화 수준 맞추기 (15분)

담당 기능 하나를 골라 상태를 10개 이상 나열한 뒤, 각 상태를 두 질문으로 판정한다 — 테스트 코드가 이 상태를 관찰 할 수 있는가(API 응답·화면 요소· DB 값 중 하나로), 이 상태로 가는 전이를 일으킬 수 있는가. X 가 하나라도 있는 상태는 합치거나 제거하고, 처음 목록과 최종 목록의 개수를 비교해 적는다.

자가 체크리스트

  • MBT 도입이 유지보수 대상을 케이스 문서에서 모델로 옮긴다는 점을 설명할 수 있다
  • UML 상태기계의 상태·전이·가드·액션을 구분하고, 모델 변수로 상태 폭발을 줄이는 방법을 안다
  • BPMN 이 상태기계보다 적합한 업무의 특징(역할·반송·기한·메시지)을 들 수 있다
  • 조건 조합이 본질인 로직을 상태기계로 그리면 왜 망가지는지 설명할 수 있다
  • 도달 불가 상태와 데드엔드를 찾아내고, 의도된 종료 상태와 구분할 수 있다
  • 비결정 전이를 가드의 배타성 검사로 판정하고 수정안을 제시할 수 있다
  • 가드 누락이 중복보다 발견하기 어려운 이유를 설명할 수 있다
  • 상태의 적정 추상화 수준을 관찰 가능성·제어 가능성으로 판정할 수 있다
  • 금지 전이를 테스트하려면 부정 전이를 모델에 명시해야 함을 안다

흔한 실수

  • 모델을 리뷰 대상에 올리지 않는다. 케이스 목록은 리뷰하면서 그 케이스를 만들어 낸 모델은 아무도 보지 않는다. 리뷰 순서가 거꾸로다.
  • 모델에 구현 단계를 그려 넣는다. API_호출중·큐_대기중 처럼 관찰도 제어도 안 되는 상태가 들어오면 케이스 수만 늘고 검증은 비어 있다.
  • 상태 이름으로 수량을 표현한다. 실패1회·실패2회… 를 상태로 만들면 모델이 선형으로 불어난다. 모델 변수와 가드로 옮긴다.
  • 가드를 겹치게 쓰고 "도구가 알아서 고르겠지" 로 넘긴다. 그 임의 선택이 뒤에 간헐적 실패로 돌아오고, 원인을 코드에서 찾느라 며칠을 쓴다.
  • 빈칸을 모델에 넣지 않고 "MBT 를 도입했으니 상태 테스트는 끝" 으로 본다. 모델은 정의된 전이만 커버한다.

참고 자료

  • OMG — Unified Modeling Language (UML) Specification — 상태기계의 상태·전이·가드·액션, 계층 상태와 직교 영역의 표준 정의. StateMachines 장 원문 확인
  • OMG — Business Process Model and Notation (BPMN) Specification — 태스크·게이트웨이·레인·메시지 흐름·경계 이벤트의 표준 정의
  • ISTQB — Certified Tester Model-Based Tester (CT-MBT) — 실러버스의 "MBT Modeling" 장이 모델링 언어와 모델링 good practice 를 다룬다. v1.1 은 v1.0(2015)의 소폭 개정판으로 CTFL v4.0 과 정렬됐다고 공지돼 있다 — 세부 학습 목표는 실러버스 원문 확인
  • 모듈 3 레슨 3·레슨 11 — 상태 전이 표와 결정 표, MBT 개념과 생성 파이프라인. 이 레슨은 그 모델의 품질 판정을 다룬다

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

MBT — 모델 기반 테스팅
화면 흐름이나 상태 변화를 그림(모델)으로 먼저 그리고, 거기서 시험할 경로를 기계적으로 뽑아내는 방식.
BPMN — 업무 프로세스 표기법
업무 흐름을 도형으로 그리는 표준 표기법.
CI — 지속적 통합
코드를 올릴 때마다 자동으로 합쳐서 빌드하고 시험까지 돌리는 방식.
API — 응용 프로그램 인터페이스
프로그램끼리 주고받는 창구. 사람이 화면 버튼을 누르는 대신, 프로그램이 정해진 주소로 요청을 보내 답을 받는다.
DB — 데이터베이스
데이터를 넣어 두고 꺼내 쓰는 저장소. 보통 표 여러 개가 서로 연결된 형태다.
OMG — 오엠지
모델링 표기법 표준을 만드는 국제 단체.
ISTQB — 국제 소프트웨어 테스팅 자격 위원회
테스터 자격 시험을 만들고 용어를 정리하는 국제 단체.
CTFL — 기초 등급 테스터 자격
테스터 자격의 가장 기초 단계. 용어와 기본 기법을 다룬다.

용어집 전체 보기