콘텐츠로 이동

검증

테스트를 채운 다음, 그 테스트가 스펙대로 커버하는지, flaky하지 않은지, 셀렉터가 취약하지 않은지, 실키가 새지 않았는지를 한 번 묻는 자리가 필요합니다. /run-suite가 동작을 보고, /review-e2e가 정적 품질을 봅니다. 한쪽만 통과해서는 진짜 통과가 아닙니다.

도구보는 자리
/run-suite동작. 선택 트랙을 실행하고 크리티컬 플로우 언어로 결과를 합성
/review-e2e정적. 6차원 루브릭으로 구조 품질을 평가

raw 리포터 출력은 사용자에게 그대로 가지 않습니다. e2e-spec.md §2 플로우 단위로 다시 묶입니다. 통과는 한 줄, 실패만 무엇, 어디, 추정 원인, 다음 단계를 답니다.

## 동작 검증 결과 — web
✓ 비로그인 방문자가 가격 페이지에서 Pro 결제 → 대시보드 진입
✓ 로그인 사용자가 설정에서 프로필 수정
✗ 로그인 사용자가 결제 관리(Customer Portal) 이동
- 위치: tests/web/specs/billing.spec.ts:42
- 메시지: customer-portal 호출이 401
- 추정 원인: Authorization 헤더 누락 또는 세션 만료
- 다음: implement-web-suite 재호출 — 세션 추출 부분 검토

assertion line은 보고서 파일(run-{ISO}.md)에만 남기고, 전체 로그는 .claude/state/last-run.log에 통째로 들어갑니다. 출력이 50줄을 넘으면 컨텍스트에는 error와 warning만 흘립니다(Silence on Success).

루브릭의 SSOT는 AI_AUTOMATION.md §7입니다. 각 차원 5/3/1점이고, 통과는 모든 차원 3점 이상입니다.

차원5점1점
커버리지§2 크리티컬 플로우 모두 테스트 존재핵심 플로우 미커버
flakiness하드 sleep 0, 재실행 안정, retry 정책 명시sleep 남발, 불안정
셀렉터 품질role/label/testID 우선, CSS/XPath 0XPath와 취약 셀렉터 다수
테스트 격리컨텍스트, DB, 디바이스 상태 격리, 인증만 재사용순서 의존, 전역 상태
실행 성능병렬과 샤딩, 합리적 시간과도하게 느림, 중복
유지보수성POM 재사용, fixture 정리, 명확한 실패 메시지로케이터 흩어짐, 읽기 어려움

검증자는 근거 없는 5점을 주지 않습니다(Evaluator Calibration). 의심되면 낮춰 잡고 fix suggestion을 답니다. flakiness는 grep -rn 'waitForTimeout\|sleep'로 잡고, 셀렉터 품질은 grep으로 CSS/XPath 남용을 셉니다. 결과는 차원별 점수와 근거와 함께 .claude/state/review-{ISO}.md에 한 장 떨어집니다.

AI_AUTOMATION.md §5가 reviewer가 차단하는 패턴을 들고 있습니다. 대부분 grep으로 잡히는 자리입니다.

금지대체
하드 sleep, waitForTimeout(n)flaky의 1순위 원인auto-wait, web-first assertion, waitForResponse, idle 동기화(Detox)
CSS/XPath 셀렉터 남용DOM 변경에 취약getByRolegetByLabel/getByText → 최후수단 getByTestId(mobile은 testID)
프로덕션 SUT, DB 접근데이터 오염, 사고로컬/스테이징/전용 테스트 환경(S6)
웹뷰 컨텍스트 ID 하드코딩실행마다 달라짐getContextHandles()로 조회 후 전환
브라우저 바이너리 캐싱(CI)버전 불일치, OS 의존성매번 playwright install --with-deps
Electron 네이티브 UI 직접 클릭자동화 불가메인 프로세스 API를 evaluate/stub
테스트 간 상태 공유순서 의존, flaky테스트마다 새 컨텍스트, 인증만 storageState 재사용
실키를 spec/CI 로그에 노출유출env와 시크릿 저장소, 마스킹(S2, S7)

AI_AUTOMATION.md §4의 여덟 줄입니다. e2e 도메인에 맞춰 박힌 자리입니다.

  • S1 최소 권한. 테스트 계정은 전용이고 저권한입니다. 관리자나 실사용자 계정으로 e2e를 돌리지 않습니다.
  • S2 시크릿 격리. 실키와 비밀번호는 코드나 리포에 박지 않습니다. .env.test.local(gitignored)만 쓰고, 리포에는 .env.test.example의 키 목록만 둡니다.
  • S3 입력 검증. 외부에서 받은 SUT URL과 자격증명을 그대로 신뢰하지 않고 형식을 검증합니다.
  • S4 출력 감사. trace, video, 스크린샷에 토큰이나 PII가 찍히면 마스킹합니다. 아티팩트 공개 범위를 주의합니다.
  • S5 파괴적 명령 차단. db reset이나 계정 삭제는 명시 확인 후에만. 트랙이나 디렉토리를 지우기 전에도 사용자 확인을 받습니다.
  • S6 환경 격리. 프로덕션 SUT와 프로덕션 DB 접근은 절대 금지입니다. 로컬, 스테이징, 전용 테스트 환경만.
  • S7 로그 마스킹. 보고서와 로그에 자격증명과 세션 토큰을 노출하지 않습니다.
  • S8 외부 통신 감사. 테스트가 호출하는 외부 엔드포인트를 명시하고, 실결제나 실발송 같은 부작용은 test mode로 차단합니다.

S6과 S2가 이 도메인에서 가장 먼저 차단되는 자리입니다. 프로덕션에 붙거나 실키가 새면 그 자리에서 멈춥니다.

/review-e2echanges_requested를 반환하면 대상 트랙과 차원을 명시하고 그 트랙의 implement-*를 재호출합니다. reviewer는 코드를 고치지 않고 builder가 그 부분만 외과적으로 수정합니다. 이 루프는 iteration 두 번까지입니다. 두 번 연속 막히면 stage가 blocked로 바뀌고 /recover-from-blocked가 트리거 자리에 들어갑니다. 비개발자 호흡으로 같은 복구 흐름을 푼 자리는 비개발자용 when-ai-gets-stuck에 있습니다.

Terminal window
/run-suite # 선택 트랙 실행 + 시나리오 언어 보고
/review-e2e # 6차원 합성
PM="$(jq -r '.name' .claude/state/package-manager.json)"
$PM exec playwright test --project=chromium # web 직접
$PM exec playwright test --project=electron # electron 직접 (Linux 로컬은 xvfb-run 래핑)
maestro test tests/mobile/flows # mobile (Maestro)

다음 섹션은 ci입니다. .github/workflows/e2e.yml이 트랙별로 어떻게 갈리는지, web 샤딩과 blob 머지, electron의 Linux 전용 xvfb, mobile의 emulator와 cloud를 봅니다.