← 염승준
04

테스트를 설계 문제로 다루기

라이브러리에선 회귀를 증명하려고, 어드민에선 API 없이 먼저 출발하려고.

문제
  • npm에 배포하는 라이브러리라 "내가 안 깨뜨렸다"를 스스로 증명해야 했음
  • B2G 어드민은 백엔드 API가 확정되기 전에 프론트엔드를 먼저 시작해야 했음
해결
  • 함수마다 기본 동작·엣지 케이스·에러 처리를 검증. 클립보드는 전역 모킹, 타이머는 가짜 타이머
  • 테스트하기 어려운 함수는 테스트를 억지로 짜기보다 환경 의존부터 분리
  • zod 스키마를 API 계약 초안으로 두고, MSW가 실제 엔드포인트 URL을 가로채게 해 앱 코드에 목 분기를 두지 않음
  • (진행 중) E2E 시나리오 작성은 AI에 맡기고 누락 검토·승인은 직접, 승인된 시나리오만 AI가 실행
결과
  • 라이브러리 커버리지 약 90%, CI에서 타입 검사·테스트 자동 실행
  • 환경변수 토글만으로 실서버 전환. 계약이 바뀌면 스키마 한 곳만 수정

개인 라이브러리에서: 회귀를 스스로 증명하기

남이 쓸 코드를 npm에 배포하다 보니 "내가 안 깨뜨렸다"를 스스로 증명해야 했습니다. Vitest로 함수마다 기본 동작·엣지 케이스·에러 처리를 검증해 커버리지 약 90%를 확보하고, 타입 검사와 테스트를 CI에서 자동 실행해 배포 전에 회귀를 막았습니다.

까다로웠던 건 환경에 의존하는 함수들이었습니다. 클립보드 복사는 최신 API와 레거시 방식 두 경로를 모두 검증해야 해서 전역을 모킹했고, sleep 같은 타이머 함수는 가짜 타이머로 실제 대기 없이 비동기 타이밍을 확인했습니다.

테스트하기 어려운 함수는 대개 설계가 환경에 붙어 있다는 신호였습니다. 그럴 때는 테스트를 억지로 짜기보다 함수를 먼저 갈랐습니다.

실무 어드민에서: API 없이 먼저 출발하기

B2G 선수관리 어드민은 백엔드 API가 확정되지 않은 시점에 프론트엔드를 먼저 시작해야 했습니다. zod 스키마를 API 계약 초안으로 정의하고, MSW가 실제 엔드포인트 URL을 가로채도록 구성했습니다.

핵심은 앱 코드에 목 분기를 남기지 않은 것입니다. if (isMock) 같은 조건이 코드에 들어가면 나중에 전부 걷어내야 하고, 걷어내는 과정에서 실서버 경로가 처음 실행됩니다. URL을 가로채는 방식이면 앱은 항상 진짜 요청을 보내고 있다고 믿으므로, 환경변수 토글만으로 실서버 전환이 끝납니다.

계약이 바뀌면 스키마 한 곳만 고치면 목과 런타임 검증이 함께 따라옵니다. 이 어드민 전체 이야기는 B2G 선수관리 어드민에 따로 적었습니다.

코딩 에이전트: 맡길 일과 판단할 일

Claude Code에 스킬을 적용하거나 직접 만들어 쓰고, 테스트 코드 작성 플로우·PR 생성·Figma MCP 연결 에이전트를 팀에 공유해 팀이 반복해 쓰는 방식으로 옮겼습니다.

지금은 E2E 테스트 도입을 진행하고 있습니다. 스토리 단위로 정리한 구현 내용을 바탕으로 AI에 시나리오 작성을 맡기되, 빠진 시나리오가 없는지 검토하고 승인하는 일은 직접 합니다. 승인된 시나리오만 AI가 브라우저에서 실행하도록 설계하고 있습니다. 무엇을 검증할지는 사람이 정하고, 반복 작성과 실행은 에이전트에 맡기는 구분입니다.