개념
모듈 3(레슨 3)과의 차이
모듈 3(레슨 3)에서 상태 전이 테스트를 배웠다 — 명세를 보고 상태 다이어그램을 먼저 그린 뒤 그 다이어그램을 근거로 테스트 케이스를 설계했다. 이 레슨은 순서가 반대다. 명세에 상태가 다 정리되어 있지 않거나, 실제 구현이 명세와 다를 수 있다는 전제 위에서, 탐험하며 상태 모델을 그 자리에서 발견하고 그려나간다.
두 레슨의 관계를 한 줄로 쓰면 이렇다.
| 모듈 3 레슨 3 | 이 레슨 | |
|---|---|---|
| 출발 | 문서에 적힌 상태 목록 | 돌아가는 화면 |
| 하는 일 | 그림에서 케이스를 뽑는다 | 그림을 그린다 |
| 전제 | 목록이 맞다 | 목록이 불완전하다 |
| 산출 | 테스트 케이스 | 상태 지도 + 결함 |
앞 레슨(개체와 관계)이 가로 방향 지도였다면, 이 레슨은 세로 방향이다. "주문" 이라는 개체 하나가 시간에 따라 어떤 모습을 거치는지 본다.
상태란 무엇인가 — 세 가지 신호
"상태" 가 추상적으로 느껴지면 화면에서 찾는 법부터 보면 된다. 셋 중 하나가 보이면 그건 상태다.
하나, 이름이 붙어 있다. "결제 대기", "배송 중", "승인 반려" 처럼 화면에 글자로 적혀 있다. 가장 쉬운 경우다.
둘, 할 수 있는 일이 달라진다. 같은 주문인데 어떤 때는 취소 버튼이 보이고 어떤 때는 안 보인다. 버튼이 나타났다 사라지는 것 자체가 상태의 증거다.
셋, 같은 행동의 결과가 다르다. 같은 버튼을 눌렀는데 어제는 되고 오늘은 "이미 처리됨" 이 뜬다. 눈에 보이는 표시가 없어도 안에서는 상태가 바뀌어 있다.
세 번째가 가장 위험하다. 보이지 않는 상태이기 때문이다. 사용자는 왜 안 되는지 모르고, QA 도 화면만 보면 못 찾는다. 레슨 4의 "네 겹" 에서 저장소를 봐야 하는 이유가 여기서도 나온다.
발견하며 그리기
탐험을 시작하면서 노트나 화이트보드에 상태 다이어그램을 그리기 시작한다. 액션을 할 때마다 "지금 어떤 상태에 있는가"를 표시하고, 예상 못 한 상태에 도달하면 그것도 다이어그램에 추가한다.
먼저 그리고 시작하지 않는다는 점이 중요하다. 미리 완성된 그림을 들고 들어가면 그 그림에 맞는 것만 보게 된다. 빈 종이에서 시작해 본 대로 채워 나간다.
"주문" 상태가 공식 문서엔 4가지(결제대기/결제완료/배송중/배송완료)로 적혀 있었다. 그런데 탐험 중 "결제 시도 중 브라우저를 닫아버린" 케이스를 해봤더니, 시스템이 "결제대기"도 "결제완료"도 아닌 애매한 상태로 남아 있었다 — 이건 문서에 없던 다섯 번째 상태다.
그 다섯 번째 상태에서 무엇을 더 물어야 하는지가 이 기법의 핵심이다. 상태를 찾은 것으로 끝내지 않고 그 상태에서 다시 탐험한다.
그 애매한 상태에서 결제를 다시 시도하면? 취소는 되나? 관리자 화면에는 뭐라고 보이나? 하루 뒤에는 어떻게 되나? 재고는 묶여 있나?
질문 다섯 개가 더 나왔고, 그중 하나가 진짜 결함일 가능성이 높다. 새 상태는 끝이 아니라 새로운 출발점이다.
이렇게 발견한 상태는 그 자체로 결함일 수도 있고(의도치 않은 상태), 혹은 그냥 문서화가 안 됐을 뿐 정상적인 상태일 수도 있다 — 어느 쪽이든 몰랐던 상태를 찾아냈다는 것 자체가 탐험의 성과다.
숨은 상태가 생기는 다섯 자리
막연히 찾기보다 생기는 자리를 알고 찌르는 편이 빠르다. 다섯 군데가 반복해서 나온다.
하나, 중간에 끊긴 자리. 결제·업로드·가입처럼 여러 단계를 거치는 일은 중간에 멈추면 어디에도 속하지 않는 상태가 남는다. 문서는 시작과 끝만 적는다.
둘, 외부를 다녀오는 자리. 결제사·인증 기관에 갔다가 돌아오는 사이, 우리 쪽은 "보냈지만 결과를 모르는" 상태가 된다. 그 사이에 사용자가 창을 닫으면 그 상태로 굳는다.
셋, 시간이 만드는 자리. 만료·보류·자동 취소. 아무도 아무 행동을 안 했는데 상태가 바뀐다. 그래서 탐험 중에는 잘 안 보이고, 다음 날 와서 보면 달라져 있다.
넷, 되돌리는 자리. 취소 → 취소 철회, 반려 → 재승인, 환불 중 → 환불 실패. 앞으로 가는 길은 설계되고 되돌아오는 길은 덜 설계된다(레슨 6).
다섯, 둘이 동시에 바꾸는 자리. 사용자가 취소하는 동시에 관리자가 승인하면 어느 쪽이 이기는가. 둘 다 반영되면 모순된 상태가 된다.
다섯 중 첫째와 셋째가 가장 흔하다. 그리고 둘 다 일부러 만들지 않으면 안 생긴다 — 중간에 끊으려면 일부러 창을 닫아야 하고, 시간이 만드는 상태는 시각을 바꾸거나 기다려야 한다(레슨 5).
"이게 정말 다야?"라고 계속 묻기
상태 모델을 발견할 때 가장 중요한 질문은 "이 목록이 정말 전부인가?"다. 공식 문서나 다른 사람이 알려준 상태 목록을 그대로 믿지 않고, 의도적으로 비정상적인 경로(레슨 6에서 배운 순서 바꾸기, 중간에 멈추기, 동시 조작 등)를 시도해 숨겨진 상태를 캐낸다.
질문을 구체적으로 바꾸면 이렇게 된다.
- "실패하면 어디로 가나?" — 성공 경로만 그려진 그림이 대부분이다
- "여기서 멈추면 어디에 있나?" — 중단한 자리가 곧 중간 상태다
- "되돌리면 원래대로 가나?" — 취소의 반대말이 늘 있는 것은 아니다
- "아무것도 안 하면 뭐가 되나?" — 시간이 만드는 전이
상태보다 전이가 더 많이 샌다
상태를 다 찾았다고 끝이 아니다. 상태가 5개면 이론상 전이는 20개이고, 그중 대부분은 "일어나면 안 되는" 전이다. 그리고 막아야 하는 전이를 안 막은 것이 전형적인 결함이다.
표로 그려 보면 빈칸이 보인다.
| 지금 상태 \ 다음 | 결제대기 | 결제완료 | 배송중 | 취소됨 |
|---|---|---|---|---|
| 결제대기 | — | 정상 | 막아야 | 정상 |
| 결제완료 | 막아야 | — | 정상 | 정상(환불) |
| 배송중 | 막아야 | 막아야 | — | 애매 |
| 취소됨 | 막아야 | 막아야 | 막아야 | — |
굵게 표시한 칸들이 실제로 확인해야 할 자리다. 특히 두 군데를 본다.
- 취소됨 → 결제완료: 취소한 주문에 결제가 들어오면? 외부 결제사의 응답이 늦게 도착하는 경우에 실제로 생긴다
- 배송중 → 취소됨: "애매" 라고 적은 칸이다. 정책이 있어야 하는데 대개 아무도 정하지 않았다. 묻는 것 자체가 성과다
이 표를 그리는 데 10분이면 되고, 빈칸이 그대로 차터 목록이 된다. 모듈 3 레슨 3의 상태 전이 표와 모양은 같지만, 거기서는 문서를 보고 채우고 여기서는 해 보면서 채운다.
전이를 일으키는 것이 사람만은 아니다
전이를 찾을 때 버튼만 보면 절반을 놓친다. 상태를 바꾸는 주체가 넷이다.
| 누가 | 예 |
|---|---|
| 사용자 | 버튼을 누른다 |
| 다른 사람 | 관리자가 승인·반려, 판매자가 발송 처리 |
| 외부 시스템 | 결제사 응답, 배송사 상태 갱신 |
| 시간 | 만료, 자동 취소, 정기 배치 |
아래 셋은 내가 아무것도 안 해도 일어난다. 그래서 화면을 열어 두고 기다리거나, 다른 계정으로 조작하거나(레슨 6의 두 창), 시각을 바꿔야 보인다. "내가 안 했는데 바뀌는 길" 을 찾는 것이 이 레슨에서 가장 생산적인 질문이다.
찾은 상태를 어떻게 보고하나
"문서에 없는 상태를 찾았다" 는 그 자체로는 결함 리포트가 아니다. 셋 중 어느 쪽인지 가려서 올린다.
| 성격 | 어디로 | 어떻게 적나 |
|---|---|---|
| 문서에 없을 뿐 정상 | 기획·문서 쪽 | "이 상태가 문서에 없습니다. 추가 제안" |
| 사용자가 갇힌다 | 결함 | 어디서 갇히는지, 빠져나갈 길이 없다는 것 |
| 모순된 상태가 된다 | 결함(심각) | 두 축이 어긋난 증거를 함께 |
두 번째와 세 번째를 구분해서 적는 것이 중요하다. 갇히는 것은 사용자 한 명의 불편이고, 모순된 상태는 돈·재고·정산이 틀어지는 문제라 우선순위가 다르다.
첫 번째를 "결함 아님" 이라고 그냥 넘기지 않는 것도 중요하다. 문서에 없는 상태는 다음 사람도 모른다. 추가 제안을 남겨 두면 그 자리에서 팀의 자산이 된다.
발견의 결과물은 팀에 남긴다
이 탐험 세션이 끝나면, 그 자리에서 그린 상태 다이어그램 자체가 훌륭한 산출물이 된다 — 팀에 실제 시스템 상태 모델을 문서로 남기는 부수 효과가 있다. 특히 문서가 없던 레거시 시스템(레슨 11에서 다룬다)에서 이 방법이 빛을 발한다.
사례 — 공식 4개, 실제 9개
한 예약 서비스에서 상태를 발견해 나간 기록이다. 공식 문서에는 4개가 적혀 있었다 — 예약완료 / 이용완료 / 취소됨 / 노쇼.
탐험 두 시간 뒤 그림에는 9개가 있었다.
| 추가로 발견한 상태 | 어떻게 나왔나 | 결함인가 |
|---|---|---|
| 결제 대기 | 예약은 눌렀는데 결제창에서 창을 닫았다 | 정상(문서 누락) |
| 취소 요청됨 | 취소를 눌렀는데 업체 승인이 필요했다 | 정상(문서 누락) |
| 환불 처리 중 | 취소 승인 뒤 돈이 아직 안 들어왔다 | 정상(문서 누락) |
| 환불 실패 | 카드가 만료된 계정으로 취소해 봤다 | 결함 — 사용자에게 안내가 없다 |
| 이용 시각 지남, 처리 안 됨 | 예약 시각 다음 날까지 기다렸다 | 결함 — 노쇼도 이용완료도 아니다 |
세 개는 그냥 문서가 없었던 것이고 두 개는 진짜 결함이었다. 그리고 문서에 없던 세 개도 쓸모가 있다 — 그 상태들을 문서에 추가한 것만으로 고객센터의 "지금 어떤 상태인가요" 문의 응대가 빨라졌다.
여기서 봐야 할 것이 하나 더 있다. 다섯 개 중 네 개가 "중간 상태" 다. 시작도 끝도 아닌, 무언가를 기다리는 중인 상태들이다. 문서는 시작과 끝을 적고, 결함은 그 사이에 산다.
어떻게 그리나 — 종이 한 장이면 된다
도구는 필요 없다. 탐험하면서 네모와 화살표만 그린다. 규칙 셋만 지키면 남에게 보여 줄 수 있는 그림이 된다.
- 네모 안에는 화면에 보이는 그 글자를 그대로 적는다. "결제대기" 를 "결제 전" 으로 바꿔 적으면 나중에 못 알아본다
- 화살표 위에 무엇이 일으켰는지 적는다. "결제 버튼", "30분 경과", "관리자 승인"
- 확인 못 한 것은 물음표로 남긴다. 지우지 않는다
[결제대기] ──결제 성공──> [결제완료] ──발송──> [배송중]
│ │ │
└──30분 경과──> [자동취소]│ │
│ └──환불──> [취소됨] <┘?
│
└──창 닫음──> [ ??? ] ← 문서에 없다. 다시 열면 결제대기로 보이는데
관리자 화면에서는 "결제중" 으로 보인다마지막 줄 같은 메모가 이 그림의 값이다. 깔끔한 그림보다 "여기가 이상하다" 가 적힌 그림이 쓸모 있다.
그림은 세션이 끝나면 바로 공유한다. 머릿속에 두면 하루 만에 사라지고, 공유하면 개발자가 "아 거기는 이래서요" 를 바로 알려 준다. 그 한마디로 결함인지 의도인지 그 자리에서 가려진다.
상태가 여러 개 겹칠 때
실제 제품에서는 한 개체가 상태를 여러 축으로 동시에 가진다. 주문 하나에 결제 상태·배송 상태·정산 상태가 따로 있는 식이다.
| 축 | 값 |
|---|---|
| 결제 | 대기 / 완료 / 환불중 / 환불완료 |
| 배송 | 준비 / 출고 / 배송중 / 완료 |
| 정산 | 대기 / 정산완료 |
세 축을 곱하면 조합이 수십 가지인데, 대부분은 일어나면 안 되는 조합이다. "결제 대기인데 배송 중" 같은 것들이다.
전부 확인할 수는 없으니 모순된 조합부터 찾는다. 찾는 방법은 단순하다 — 두 축이 서로 반대 방향으로 움직이는 순간을 노린다.
배송이 시작된 직후에 환불을 요청하면? 정산이 끝난 뒤에 환불이 들어오면?
두 질문 다 타이밍이 걸려 있고, 돈이 걸려 있다. 레슨 5의 조합 기준 그대로이고, 실제로 이런 자리에서 사고가 난다.
축이 여러 개라는 것을 모르면 "주문 상태" 하나만 보다가 다른 축이 어긋난 것을 통째로 놓친다. 상태 지도를 그릴 때 축이 몇 개인지부터 확인하는 이유다.
상태를 직접 못 보는 경우
화면에 상태 이름이 안 적힌 제품도 많다. 그때는 간접 신호로 추정한다.
| 신호 | 무엇을 알 수 있나 |
|---|---|
| 버튼이 보였다 안 보인다 | 상태가 바뀌었다 |
| 같은 행동의 결과가 달라진다 | 상태가 바뀌었다 |
| 목록의 분류·정렬이 달라진다 | 분류 기준 자체가 상태인 경우가 많다 |
| 알림·메일이 온다 | 전이가 일어난 시점을 알려 준다 |
| 관리자 화면 | 사용자 화면에 없는 상태 이름이 적혀 있다 |
관리자 화면이 가장 빠른 길이다. 사용자에게는 "처리 중" 하나로 보이는 것이 관리자 화면에서는 네 단계로 나뉘어 있는 경우가 흔하다. 접근 권한이 있다면 거기부터 본다.
알림·메일도 좋은 단서다. 메일이 왔다는 것은 전이가 일어났다는 뜻이고, 메일 제목이 곧 상태 이름인 경우가 많다.
중간 상태를 특히 본다
사례에서 본 것처럼 결함은 중간 상태에 산다. 이유가 분명하다 — 중간 상태는 머무르려고 만든 곳이 아니라 지나가려고 만든 곳이기 때문이다. 설계자는 그곳에 오래 머무는 경우를 생각하지 않는다.
중간 상태를 찾으면 세 가지를 묻는다.
하나, 여기서 얼마나 오래 있을 수 있나. 몇 초를 가정하고 만든 자리에 사용자가 하루를 머물면 무슨 일이 생기나. 타임아웃이 있나, 자동으로 다음으로 가나, 영원히 남나.
둘, 여기서 할 수 있는 일이 뭔가. 취소할 수 있나, 다시 시도할 수 있나, 아니면 아무것도 못 하고 기다려야 하나. 아무것도 못 하는 상태에 갇히는 것이 사용자에게 가장 나쁘다.
셋, 사용자가 이 상태를 알 수 있나. 화면에 "처리 중" 이라고 뜨나, 아니면 그냥 아무 일도 안 일어난 것처럼 보이나. 보이지 않는 중간 상태가 "눌렀는데 아무 반응이 없어요" 문의의 정체인 경우가 많다.
세 질문 다 요구사항에 답이 없는 것이 보통이고, 그래서 묻는 것 자체가 성과가 된다(모듈 2).
실무에서 왜 필요한가
실제 시스템은 문서화된 것보다 항상 상태가 더 많다 — 예외 처리 경로, 타임아웃, 동시성으로 인한 경합 상태(race condition) 등이 문서에는 안 적히기 때문이다. 이런 "문서에 없는 상태"에서 결함이 자주 나온다.
그리고 이 작업의 산출물은 결함보다 오래 남는다. 상태 지도는 한 번 그리면 제품이 크게 바뀌기 전까지 계속 쓰인다.
- 다음 탐험의 출발점 — 빈칸과 물음표가 차터가 된다
- 케이스 설계의 재료 — 모듈 3 레슨 3이 전제하는 "완전한 상태 목록" 이 비로소 생긴다
- 새로 온 사람의 교재 — 화면 설명서보다 상태 지도 한 장이 빠르다
- 개발·기획과의 공용어 — "그건 환불 처리 중 상태인데요" 처럼 같은 이름으로 말하게 된다
마지막 항목이 생각보다 크다. 상태에 이름이 없으면 "그 돈 안 들어온 거요" 처럼 사람마다 다르게 부르고, 그 차이가 그대로 소통 비용이 된다. 상태를 실시간으로 발견하며 탐험하는 능력은, 모듈 3의 상태 전이 테스트가 애초에 전제하는 "완전한 상태 목록"이 실제로는 없다는 현실에 대한 QA의 실전 대응이다.
채용시장에서의 위치
상태를 다룰 줄 아는지는 면접에서 한 질문으로 바로 드러난다.
- "주문 기능을 테스트한다면 무엇부터 보시겠어요?" — "주문이 되는지" 는 초급 답이다. "주문이 가질 수 있는 상태를 먼저 적고, 그 사이에 일어나면 안 되는 전이부터 봅니다" 가 이 레슨의 답이다
- "문서가 없는 기능은 어떻게 테스트하시나요?" — 상태 발견이 그 답이다. "돌려 보면서 상태 지도를 그리고 모르는 부분은 물어봤습니다"
- "동시성 문제를 다뤄 본 적 있나요?" — 상태 관점에서 답하면 깊이가 다르다. "둘이 동시에 바꾸면 모순된 상태가 되는지 봤습니다"
그리고 그려 본 상태 지도는 포트폴리오가 된다. 실제로 만든 산출물을 보여 줄 수 있는 몇 안 되는 탐색적 테스팅 결과물이고, 면접에서 "이렇게 정리했습니다" 하고 내놓으면 말로 설명하는 것보다 훨씬 강하다(모듈 42).
금융·커머스·예약 서비스 공고에서는 "상태 관리", "주문 라이프사이클 검증" 같은 문구로 나온다. 전부 이 레슨의 다른 이름이다.