책의 첫 장이자 TDD의 첫 사이클이다. 다중 통화 보고서라는 요구사항 앞에서 벡은 설계 문서를 펴지 않는다. 할 일 목록을 적고, 그중 가장 작은 항목의 실패하는 테스트부터 쓴다. 이 장이 보여주는 것은 기법이 아니라 리듬이다 — 빨강(실패) → 초록(통과) → 리팩터링.
할 일 목록이 설계 문서를 대신한다
10 (환율이 2:1일 경우) — 이게 최종 목표다. 하지만 첫 테스트는 그보다 훨씬 작은 $5 × 2 = $10이다. 목록에서 지금 당장 다룰 수 있는 가장 작은 항목을 고르고, 나머지는 목록에 남겨 둔다. 머릿속에 담아두지 않으니 지금 한 걸음에 집중할 수 있다.
판단 기준: 테스트 하나를 고르는 기준은 “가장 중요한 것”이 아니라 “지금 확실히 통과시킬 수 있는 가장 작은 것”이다. 함정: 첫 테스트부터 완벽한 API를 설계하려 들면 리듬이 시작되지 않는다. 테스트는 API의 초안이고, 초안은 고치면 된다.
한 사이클: 빨강 → 초록 → 리팩터링
아래 스텝 플레이어가 이 장의 전부다. 컴파일도 안 되는 테스트에서 시작해, 가짜 구현(죄악)으로 초록을 만들고, 중복을 지우며 진짜 구현에 도달한다.
public class MoneyTest { @Test public void testMultiplication() { Dollar five = new Dollar(5); five.times(2); assertEquals(10, five.amount); }}// Dollar 클래스는 아직 존재하지 않는다. 컴파일조차 안 된다.// 컴파일 에러도 "실패"다 — 지금 필요한 최소한의 껍데기를 만든다.
amount = 10이 왜 죄악이면서 동시에 정당한가. 벡의 답: 초록 막대가 없는 상태에서의 모든 판단은 추측이다. 가짜 구현이라도 초록을 먼저 만들면, 이후의 모든 걸음을 테스트가 검증해 준다. 하드코딩된 10은 “테스트의 5×2와 코드의 10”이라는 중복이고, 리팩터링의 대상이 된다. 죄악은 저지르는 게 문제가 아니라 회개하지 않는 게 문제다.
이 장이 남긴 할 일 목록
사이클 하나가 끝나면 목록을 갱신한다. $5 × 2 = $10에는 줄을 긋고, 사이클 중 발견한 문제를 추가한다.
10- Dollar 부작용? —
five.times(2)가 five 자체를 바꾼다. 값 객체여야 하지 않나 → 2장 - amount를 public으로 노출 중
- 10 (환율 2:1)
판단 기준: 사이클 도중 발견한 설계 문제는 그 자리에서 고치지 않고 목록에 적는다. 지금 걸음과 다음 걸음을 섞지 않는 것이 리듬 유지의 핵심이다.
다음장으로 2장