Agent TDD 워크플로
이 글에서 다룰 것
AI가 코드를 쭉 뽑아주고 나면, 이런 의심 한 번쯤 드시죠 — "이거 다 된 거 맞나? 믿을 만한 품질인가? 시키지도 않은 게 슬쩍 끼어들진 않았나?" 보기엔 그럴듯한데 실제론 안 돌아가는 코드, 비일비재하거든요.
이걸 잡는 방법이 뜻밖에도 20년이나 된 방법론이에요. 바로 TDD. 사람이 직접 짤 땐 "비싸다"는 이유로 자주 외면받던 게, AI 시대에 와서 오히려 가장 강력한 레버리지로 부활했어요. 이 글은 그 부활의 이유와, AI와 함께 도는 TDD 워크플로를 풀어볼게요.
핵심 메시지
Anthropic이 공식 가이드에서 이렇게 못박았어요.
"Give Claude a way to verify its work. This is the single highest-leverage thing you can do." (클로드에게 자기 일을 스스로 검증할 방법을 줘라. 이게 당신이 할 수 있는 가장 레버리지 큰 단 하나의 일이다.)
그 "검증 수단"이 곧 TDD예요. AI 코딩에서 테스트 코드는 단순 검증을 넘어, 명세서(Agent가 따라갈 올바른 방향) + 회귀자산(이전 기능이 안 깨졌다는 보장) 이라는 두 자산을 동시에 만들어줘요. 20년 전 방법론이, AI를 만나 가장 강력한 레버리지가 된 셈이죠.
1. TDD가 뭐였더라 - 순서가 거꾸로
보통은 함수를 먼저 짜고, 나중에 테스트를 붙이잖아요.
function add(a, b) { return a + b; }
test('add works', () => { expect(add(2, 3)).toBe(5); });
TDD는 이 순서를 거꾸로 뒤집어요. 실패하는 테스트를 먼저 짜고, 그걸 통과시키는 코드를 나중에 짜는 거죠.
// 1) 테스트 먼저 — 함수가 없으니 당연히 실패(RED)
test('add works', () => { expect(add(2, 3)).toBe(5); });
// 2) 그제서야 통과시키는 코드
function add(a, b) { return a + b; }
좀 특이하죠? 근데 이 "거꾸로"에 핵심이 있어요.
2. RED → GREEN → REFACTOR - 한 바퀴
사이클은 이렇게 돌아요. RED(실패하는 테스트) → GREEN(통과시키는 최소 코드) → REFACTOR(코드 정리) → TEST(전체 회귀 검증) → 다시 반복.
TDD 사이클
3. 사실 꽤 괜찮은 방법론인데 - 비쌌던 거죠
TDD를 뜯어보면 좋은 구석이 많아요. 테스트를 먼저 짜다 보면 어쩔 수 없이 설계가 유도되거든요(그래서 "설계 방법론"이라고도 불려요). 게다가 스펙을 자세히 분석해야만 테스트를 쓸 수 있으니, 자연히 꼼꼼해지고요.
근데 현실은… "코드 짜기도 바쁜데 테스트를 먼저? 그것도 순서가 어색하고", "당장 안 해도 돌아가는데 굳이", "그냥 오픈하고 나중에 추가하지 뭐". 결국 테스트건 TDD건 비용이 비싸다는 인식에 밀렸던 거예요. 장기적으론 분명 이득인데, 당장이 바쁘니까요.
4. Anthropic의 결정타 - "검증 수단을 줘라"
그런데 AI 시대가 판을 바꿨어요. 위에 인용한 그 문장이 결정타예요.
Include tests, screenshots, or expected outputs so Claude can check itself. Without clear success criteria, it might produce something that looks right but actually doesn't work. You become the only feedback loop, and every mistake requires your attention.
(테스트·스크린샷·기대 출력을 같이 줘서 클로드가 스스로 점검하게 하라. 명확한 성공 기준이 없으면, 그럴듯해 보이지만 실제론 안 돌아가는 걸 내놓는다. 그러면 당신이 유일한 피드백 루프가 되고, 모든 실수가 당신 손을 거쳐야 한다.)
검증 기준이 없으면 사람이 유일한 피드백 루프가 돼요. 그게 얼마나 피곤한지 다들 아시죠. 그래서 프롬프트도 이렇게 달라져요.
| 프롬프트 | |
|---|---|
| Before | "이메일 검증 함수를 만들어줘" |
| After | "validateEmail 함수를 만들어줘. 예시 테스트: user@example.com은 true, invalid는 false, user@.com은 false. 구현 후 테스트를 돌려줘." |
After 쪽을 보면, 검증 리스트(=테스트 케이스)를 먼저 명시하고 있죠. 그게 결국 테스트를 먼저 정의하는 것 — 바로 TDD예요.
5. AI 시대 TDD 워크플로 - 5스텝
큰 흐름은 다섯 단계예요.
요구사항 분석 → 태스크 정리(나누기) → 태스크별 테스트 시나리오
→ 테스트 코드 → 동작하는 코드
요구사항을 분석하고(이건 사람 몫이죠), 태스크로 나누고, 태스크마다 "이걸 누르면 이게 나와야 해, 이메일이 이러면 오류가 나야 해" 식의 시나리오를 정하고, 그대로 테스트 코드를 짜게 한 다음, 마지막에 동작하는 코드를 채워요. AI를 쓰니까, 예전보다 훨씬 촘촘하게 TDD를 할 수 있게 된 거죠.
6. 한 이슈를 통과시키는 6단계
좀 더 들어가면, 이슈 하나를 통과시키는 사이클은 여섯 단계로 돌아요.
TDD 사이클 6단계 디테일
| # | 단계 | 핵심 도구·개념 |
|---|---|---|
| 1 | 시나리오 도출 | /test-scenarios, 시그니처 확정, Acceptance Criteria |
| 2 | Red · 실패 테스트 | /tdd-red, Vitest, RTL, 의도→테스트 |
| 3 | Green · 최소 구현 | /tdd-green, YAGNI, 최소 통과 |
| 4 | AC 검증 (스킬 X, 에이전트) | @ac-verifier, 탐색적 판단 |
| 5 | Refactor · 구조 개선 | /tdd-refactor, 즉시 롤백 |
| 6 | Security · Commit | /security-review, tsc --noEmit, npm audit |
이걸 이슈마다 반복하고, 다음 이슈로 넘어가요. 각 단계가 슬래시 커맨드·도구와 1:1로 묶이니, 손에 익으면 거의 리듬처럼 돌아가죠. (4번 AC 검증만 스킬이 아니라 독립 에이전트인 게 포인트예요 — 구현한 AI가 자기 코드를 자기가 채점하지 못하게 따로 떼어둔 거죠.)
7. 결과물 - 테스트 코드의 두 가지 의미
TDD를 하고 나면 손에 남는 게 코드만이 아니에요. 테스트 코드가 같이 남죠. 그리고 이 테스트 코드는 두 가지 의미를 가져요.
src/
├── utils/
│ ├── validateEmail.js
│ └── validateEmail.spec.js
└── services/
├── authService.js
└── authService.spec.js
하나는 명세서예요. AI가 나중에 기능을 고치거나 확장할 때 참고하는 스펙이라, 올바른 개발 방향을 강제하죠.
describe('주문 결제', () => {
test('재고가 없으면 결제는 실패하고, 장바구니는 유지된다', () => { ... });
});
다른 하나는 회귀자산(regression asset) 이에요. 테스트가 쫙 쌓여 있으니, 뭐 하나 수정하고 전체를 돌려보면 "응, 전에 거 안 깨졌네" 하는 안전성이 생겨요.
Test Files 66 passed (66)
Tests 280 passed (280)
Duration 9.39s
8. 그래서 쉬운가 - 솔직히, 아니요
솔직히 말하면 TDD가 쉽진 않아요. AI가 다 구현해준다 해도, 사람이 알아야 할 게 남거든요 — 테스트가 뭘 검증하는지 읽을 수 있어야 하고, TDD라는 순서 자체가 어색하고, mocking 같은 구현 방법도 알아야 하고요. 그래서 모르는 영역은 학습하며 진행하는(Learning-Driven) 자세가 같이 가야 해요.
그리고 모든 걸 다 TDD 할 필요도 없어요. 텍스트 바꾸기, 색상 바꾸기, 변수 이름 바꾸기까지 테스트를 먼저 짤 필요는 없죠. 유연함은 경험에서 와요. 처음부터 너무 엄격하게 다 하려 들지 말고, "이건 그냥 짜면 될 것 같은데" 싶은 것도 한 번씩 TDD로 해보면서 감을 잡는 정도가 좋아요.
마무리 - 두려움이 지루함이 될 때까지
AI 코딩의 가장 큰 불안은 "이게 맞게 된 건가?"인데, TDD는 그 불안을 시작 전에 검증 기준으로 바꿔놔요. 사람이 유일한 피드백 루프가 되는 걸 막아주는 거죠.
Kent Beck의 한마디로 닫을게요.
"테스트를 써라. 두려움이 지루함이 될 때까지." — Kent Beck
검증이 손에 익으면, 그 두근거림이 정말 지루함이 되거든요.
참고 영상
