"실제 사용자처럼 클릭하는 자동 테스트가 없으면, '됐어요'는 친구 앞에서 깨질 됐어요입니다. E2E는 검증 사다리의 진짜 한 칸 위입니다."
단위 테스트는 다 초록불이었습니다
지난주 토요일 저녁, 저는 친구를 다시 한번 불러 앉혔습니다. 챕터 9 이후, 검증 명령을 빠짐없이 박아둔 자신감으로요. 터미널엔 초록색 OK가 줄줄이 떠 있었습니다. 린트 통과, 타입 체크 통과, 단위 테스트 47개 모두 통과.
친구가 가입 버튼을 눌렀습니다. 이메일을 적고, 인증 코드를 받고, 첫 결제 카드를 입력하는 순간 — Tab 키로 다음 칸으로 넘어가다 폼이 리셋됐습니다. 47개 단위 테스트 중 어느 것도 Tab 키를 누르는 사람을 시뮬레이션하지 않았습니다.
단위 테스트는 부품을, E2E는 흐름을 봅니다. 사용자는 부품을 사지 않습니다.
조각의 통과와 흐름의 통과는 다른 사건입니다
단위 테스트는 함수 한 개, 컴포넌트 한 개를 조각으로 봅니다. AI가 "테스트 통과"라고 답할 때, 그건 조각들이 각자 잘 동작합니다라는 뜻입니다. 조각들 사이의 이음매가 잘 흐른다는 뜻이 아닙니다.
그런데 사용자는 정확히 그 이음매 위로 걷습니다. 가입 → 인증 메일 → 로그인 → 첫 결제 → 영수증 도착까지를 한 줄로 흘러갑니다. 어디서 한 박자 끊기는지, 어느 칸에서 폼이 리셋되는지, 모바일 키보드가 올라오면 버튼이 가려지는지 — 이건 단위 테스트가 알려주지 않습니다.
조기 완료 선언의 두 번째 얼굴이 여기에 있습니다. "테스트 통과했어요"는 "흐름이 끝까지 흐릅니다"가 아닙니다.
E2E, 사다리의 진짜 한 칸 위
E2E(End-to-End) 는 사용자처럼 한 흐름을 끝까지 클릭하는 자동 테스트입니다. 챕터 9의 검증 사다리에서 2단계 — 시나리오 검증이 정확히 여기에 해당합니다. 0단계(실행)와 1단계(결정적 검증)가 부품의 안부를 묻는다면, 2단계는 흐름의 안부를 묻습니다.
비개발자 친화 도구 세 가지를 한 줄씩 소개합니다.
- Playwright MCP — Claude Code/Cursor에서 바로 호출됩니다. AI가 직접 브라우저를 열고, 직접 클릭하고, 직접 결과 화면을 봅니다. 사람이 "이걸 눌러봐"라고만 적으면 됩니다.
- Lovable 내장 미리보기 — 만든 화면을 그 자리에서 실 클릭으로 시연할 수 있습니다. 모바일 폭 토글 한 번이면 모바일 시연도 5분.
- 녹화 + 스크린샷 검증 — 사람이 1회 시연하면 AI가 그 동선을 재현 시나리오로 굳혀줍니다. 다음부터는 같은 시나리오를 기계가 매번 다시 돌립니다.
세 도구의 공통점은 하나입니다. 사람의 눈과 기계의 끈기를 한 번에 빌려준다는 점.
사용자 시나리오를 글로 적는 법 — Given/When/Then
E2E 도구를 켜기 전에, 시나리오를 글로 먼저 적어야 합니다. 형식은 세 줄이면 충분합니다.
- Given — 시작 상태 한 줄. (예: 신규 방문자, 비로그인 상태)
- When — 사용자가 클릭·입력하는 순서 3~5단계.
- Then — 눈으로 확인되는 결과 한 줄. (영수증 화면, 이메일 도착, 잔액 변화)
결제 흐름 한 시나리오 예시입니다.
Given: 신규 방문자, 비로그인 상태
When 1: 가입 버튼 클릭 → 이메일/비번 입력 → 가입 제출
When 2: 인증 메일 링크 클릭 → 로그인 페이지로 자동 이동
When 3: 결제 페이지에서 테스트 카드 4242 입력 → 결제 제출
Then: 영수증 화면이 뜨고, 메일함에 영수증 이메일이 도착한다
이 다섯 줄을 기능을 시키기 전에 적어두면, AI는 더 이상 "구현 완료"로 도망갈 수 없습니다. Then이 눈에 보여야 끝입니다.
비개발자 사례 3개
사례 1 — 모바일 키보드에 갇힌 가입 폼. 1인 빌더 박 대표님은 Lovable로 가입 흐름을 만들고 데스크톱에서 잘 동작하는 걸 확인했습니다. 출시 다음 날 첫 사용자가 폰으로 가입을 시도했고, 모바일 키보드가 올라오자 인증 코드 입력 칸이 키보드 뒤에 숨었습니다. E2E를 모바일 폭에서 한 번도 돌리지 않아 발견하지 못한 케이스였습니다.
사례 2 — 평일은 OK, 주말은 침묵하는 요약 봇. PM 이님은 회의록 자동 요약 봇이 평일 내내 잘 도는 걸 보고 "완성"으로 마무리했습니다. 월요일 아침, 주말 회의 요약이 한 건도 와 있지 않았습니다. 시나리오에 주말 트리거가 빠져 있었던 겁니다. Given: 토요일 14시 회의가 시나리오 목록에 없었습니다.
사례 3 — 이미지 첨부 글에서만 실패하는 자동 발행. 마케터 김님은 블로그 자동 발행 워크플로를 한 달 잘 돌리다가, 어느 날부터 발행 실패가 쌓이는 걸 발견했습니다. 원인은 이미지가 첨부된 글에서만 깨지는 업로드 경로. 시나리오에 텍스트 케이스만 있고 이미지 케이스가 빠져 있었습니다.
세 사례 모두 코드는 멀쩡합니다. 빠진 건 그 사용자의 흐름을 적어둔 시나리오입니다.
시나리오 자가 점검 표
| 시나리오 | 누가 보는가 | 통과 기준 | 도구 |
|---|---|---|---|
| 가입 → 첫 결제 | 신규 사용자 | 영수증 화면 도착 | Playwright MCP |
| 비밀번호 재설정 | 기존 사용자 | 새 비번으로 재로그인 성공 | 수동 5분 시연 |
| 모바일 첫 화면 | 모바일 첫 방문자 | CTA 버튼이 손가락으로 눌림 | 폰 실기 |
| 결제 실패 복구 | 결제 실패 사용자 | 재시도 안내 노출 | 수동 |
표의 네 칸 모두 통과 기준이 눈에 보이는 형태로 적혀 있다는 점이 핵심입니다. "잘 동작함" 같은 형용사는 시나리오가 아닙니다.
오늘의 5분 액션
- 우리 프로젝트의 핵심 시나리오 3개를 종이에 글로 적으세요. Given/When/Then 형식, 한 시나리오당 다섯 줄을 넘기지 마세요.
- 그중 1개를 오늘 사람이 직접 5분 클릭으로 시연하고, 각 단계 스크린샷을 저장하세요.
feature_list.json의 해당 기능verification칸에 "E2E 시나리오 1 — Given/When/Then 통과" 한 줄을 추가하세요.- 다음 세션 명령 끝에 "이 시나리오의 통과를 스크린샷 증거로 보여줘"를 박으세요.
- 시연 중 깨진 첫 클릭이 있었다면, 그 동선을 새 시나리오로 한 줄 더 추가해 두세요.
자가 점검 5문항
- ☐ 우리 프로젝트의 핵심 시나리오 3개를 한 줄씩 답할 수 있나요?
- ☐ 마지막 출시에서 시나리오 검증을 누가 했나요?
- ☐ 모바일 케이스를 별도 시나리오로 가지고 있나요?
- ☐ AI가 "테스트 통과"라 했을 때, 그게 어떤 종류의 테스트인지 구분하나요?
- ☐ 시연하다 깨진 첫 클릭을 시나리오로 박아두었나요?
세 개 이상 아니오라면, 오늘 5분 액션이 정확히 당신을 위한 과제입니다.
마무리, 그리고 다음 챕터
다시 한번.
부품의 통과가 흐름의 통과는 아닙니다. E2E는 검증 사다리의 진짜 한 칸 위입니다.
검증이 사다리라면, 오늘 우리는 0단계와 1단계 위에 2단계 시나리오 검증을 한 칸 더 얹었습니다. 사용자가 걷는 길을 글로 적고, 기계가 매번 다시 걷게 만드는 일.
그런데 시나리오가 통과해도, 그 안에서 AI가 무엇을 했는지는 또 다른 이야기입니다. 결제는 성공했지만 그 사이 외부 API를 몇 번 호출했는지, 어디서 30초를 흘렸는지, 어떤 토큰을 얼마나 태웠는지는 시나리오가 알려주지 않습니다. 다음 챕터 11 — AI가 뭘 했는지 들여다보는 창문, 관측 가능성(Observability) 에서 그 창문을 같이 열어보겠습니다.
참고
- Eugene Yan, "How to Work and Compound with AI", eugeneyan.com/writing/working-with-ai/
- 원본 강의: walkinglabs.github.io/learn-harness-engineering/ko/ 강의 10
루틴팩 v1 — 오늘 액션을 위한 5종 템플릿
CLAUDE.md · feature_list.json · progress.md · intent_sheet.md · session-end-checklist.md
무료로 받기