테스트 주도 개발
먼저 실패하는 테스트를 작성하세요. 실패하는 것을 확인하세요. 테스트를 통과할 최소한의 코드를 작성하세요. 리팩터링하세요.
즉시 통과하는 테스트는 아무것도 증명하지 않습니다 — 버그를 잡는 모습을 본 적이 없기 때문입니다.
철칙: 실패하는 테스트 없이 프로덕션 코드는 절대 작성하지 마세요. 코드를 테스트보다 먼저 작성했다면, 삭제하고 다시 시작하세요. "참고용으로 보관"은 위장된 사후 테스트입니다 — 삭제는 삭제를 의미합니다.
사용 시기
- 새로운 기능이나 동작을 구현할 때
- 버그 수정 시 (먼저 테스트로 재현 — 증명 패턴)
- 리팩터링하거나 기존 동작을 변경할 때
- "tdd", "test-driven", "red green refactor", "테스트 주도 개발", "레드 그린 리팩터", "TDD" 키워드에 반응
사용하지 말아야 할 때: 이미 작성된 코드에 대한 테스트 생성 (이 경우 test-generation 사용); 일회성 프로토타입이나 순수 설정 (그냥 직접 구현).
예외 (사용자 확인 필요): 일회성 프로토타입, 생성된 코드, 동작에 영향을 주지 않는 순수 설정 변경.
단계
0. 먼저 스택 파악
사이클은 보편적이지만 명령어는 그렇지 않습니다. 첫 번째 테스트 전에 이 저장소가 어떻게 테스트하는지 알아내세요: package.json / pyproject.toml / Cargo.toml / pom.xml / go.mod를 읽고, ./gradlew, Makefile, CI 워크플로우, 기존 테스트 파일 명명 규칙을 확인하세요. 절대 npm test를 가정하지 마세요 — RED, GREEN, 최종 검증 모두에 저장소 자체 명령어를 사용하세요.
1. RED — 하나의 실패하는 테스트 작성
하나의 동작, 하나의 테스트, 하나의 수직 슬라이스 (지난 사이클에서 배운 것을 반영하는 추적 탄환). 당신이 존재했으면 하는 테스트를 작성하세요 — 구현이 아닌 원하는 API를 설명합니다. 명세처럼 이름을 지으세요 ("test1"이 아니라 "rejects empty email").
테스트할 결합부(seam)(공개 인터페이스)를 작성 전에 합의하세요. 확인되지 않은 결합부에서 테스트하지 마세요 — 결합부를 미리 합의하면 테스트 노력을 모든 경계 케이스 대신 중요한 경로에 집중할 수 있습니다. 모의 객체보다 실제 코드를 사용하세요; 의존성을 대체해야 한다면 가장 간단한 대체물을 사용하세요 (Real > Fake > Stub > Mock — references/test-strategy.md 참조). 모의 객체는 테스트 대상 자체가 아니라 경계를 격리합니다.
2. RED 검증 — 실패 확인
집중 테스트 명령어를 실행하세요. 다음을 확인하세요:
- 실패합니다 (에러가 아님 — 에러는 설정을 수정하고 다시 실행)
- 올바른 이유로 실패합니다 (기능 누락, 오타 아님)
- 즉시 통과하는 테스트는 기존 동작을 테스트하고 있음을 의미합니다 — 테스트를 수정하세요
3. GREEN — 최소 코드 작성
테스트를 통과하는 가장 간단한 코드. 추측성 기능, "유연성", 주변 코드 리팩터링 없음. YAGNI. 프로덕션 클래스에 테스트 전용 메서드(destroy(), reset())를 추가하지 마세요 — 정리는 테스트 유틸리티에 넣으세요.
4. GREEN 검증 — 통과 확인
집중 테스트 명령어를 실행한 다음 전체 스위트를 실행하세요. 다음을 확인하세요:
- 새 테스트가 통과합니다
- 다른 테스트가 깨지지 않았습니다 (깨졌다면 지금 수정하세요 — 건너뛰지 마세요)
- 출력이 깔끔합니다 (경고나 건너뛴 테스트 없음)
5. REFACTOR — 정리
초록색일 때만: 헬퍼 추출, 이름 개선, 중복 제거. 리팩터링 단계 후마다 테스트를 실행하세요. 동작을 추가하지 마세요. 리팩터링은 검토 단계에 속하며, 레드 → 그린 구현 사이클에 속하지 않습니다.
6. 커밋
테스트와 구현을 하나의 수직 슬라이스로 함께 커밋하세요. 그런 다음 다음 실패하는 테스트를 시작하세요.
버그 수정 — 증명 패턴
수정부터 시작하지 마세요. 버그를 재현하는 테스트를 작성하고 (RED가 존재를 확인), 그런 다음 수정하세요 (GREEN이 수정이 작동함을 증명). 테스트는 회귀 방지로 남습니다. 재현 테스트 없이 버그를 절대 수정하지 마세요.
검증
- 모든 새 동작에 먼저 실패한 테스트가 있습니다
- 전체 스위트가 저장소 자체 테스트 명령어로 통과합니다
- 버그 수정에는 수정 전에 실패한 재현 테스트가 포함됩니다
- 테스트 이름은 동작을 설명하며 구현을 설명하지 않습니다
- 건너뛰거나 비활성화된 테스트가 없고, 프로덕션 코드에 테스트 전용 메서드가 없습니다
참조
- ${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md — 모든 스킬이 공유하는 규율
- references/test-strategy.md — 테스트 피라미드, 테스트 대체 계층(Real > Fake > Stub > Mock), DAMP over DRY
- references/testing-anti-patterns.md — 모의 객체 오용, 테스트 전용 메서드, 부분 모의, 게이트 함수
- references/mocking.md — 모의 객체 사용 시기, 모의 가능성을 위한 설계
- references/good-tests.md — 좋은 테스트와 나쁜 테스트 예제, 동어반복적 테스트