← ClaudeAtlas

test-driven-developmentlisted

기능·버그픽스 구현 전에 테스트를 먼저 쓰게 강제한다. Use when 기능 구현, 버그 수정, 리팩터링, 동작 변경에 착수할 때. 구현 코드를 쓰기 전에 적용한다.
HarryJhin/groundwork · ★ 0 · Testing & QA · score 70
Install: claude install-skill HarryJhin/groundwork
# test-driven-development 테스트를 먼저 쓴다. 실패를 확인한다. 통과시킬 최소 코드를 쓴다. **핵심 원칙**: 테스트가 실패하는 것을 보지 않았다면 그 테스트가 옳은 것을 검사하는지 모른다. **규칙을 글자 그대로 지키지 않는 것은 규칙의 취지를 저버리는 것이다.** ## 적용 대상 **항상**: 새 기능, 버그 수정, 리팩터링, 동작 변경. **예외(사용자에게 묻는다)**: 버리는 프로토타입, 코드 생성기가 출력한 코드(스키마·클라이언트 스텁 등), 설정 파일. 네가 직접 쓰는 코드는 예외가 아니다. "이번만 TDD를 건너뛰자"는 생각이 들면 멈춘다. 그것이 합리화다. **경로 기준**: 이 문서의 셸 블록에 나오는 테스트 파일 경로는 대상 프로젝트의 repo 루트 기준이고, 커맨드는 그 루트에서 돈다. **테스트 러너**: 아래 블록은 Node와 jest를 예시로 쓴다. 대상 프로젝트의 테스트 커맨드로 바꿔 실행한다. **출력**: 이 스킬이 남기는 것은 테스트와 그것을 통과시키는 구현이다. 완료를 주장하기 전에 `groundwork:verification-before-completion`으로 넘긴다. ## 철칙 ``` 실패하는 테스트 없이 프로덕션 코드를 쓰지 않는다 ``` 테스트보다 코드를 먼저 썼다면 지운다. 처음부터 다시 한다. 예외는 없다. 먼저 쓴 그 코드를 이렇게 다룬다. - "참고용"으로 남기지 않는다 - 그 코드에 맞춰 테스트를 짜 맞추지 않는다 - 쳐다보지 않는다 - 지운다는 것은 지운다는 뜻이다 테스트만 보고 구현을 처음부터 다시 쓴다. ## RED-GREEN-REFACTOR ### RED. 실패하는 테스트를 쓴다 무엇이 일어나야 하는지 보여주는 최소 테스트 하나를 쓴다. 좋은 예: ```typescript test('retries failed operations 3 times', async () => { let attempts = 0; const operation = () => { attempts++; if (attempts < 3) throw new Error('fail'); return 'success'; }; const result = await retryOperation(operation); expect(result).toBe('success'); expect(attempts).toBe(3); }); ``` 이름이 명확하고, 실제 동작을 검사하고, 한 가지만 본다. 나쁜 예: ```typescript test('retry works', async () => { const mock = jest.fn() .mockRejectedValueOnce(new Error()) .mockRejectedValueOnce(new Error()) .mockResolvedValueOnce('success'); await retryOperation(mock); expect(mock).toHa