책의 첫 장이자 TDD의 첫 사이클이다. 다중 통화 보고서라는 요구사항 앞에서 벡은 설계 문서를 펴지 않는다. 할 일 목록을 적고, 그중 가장 작은 항목의 실패하는 테스트부터 쓴다. 이 장이 보여주는 것은 기법이 아니라 리듬이다 — 빨강(실패) → 초록(통과) → 리팩터링.

할 일 목록이 설계 문서를 대신한다

10 (환율이 2:1일 경우) — 이게 최종 목표다. 하지만 첫 테스트는 그보다 훨씬 작은 $5 × 2 = $10이다. 목록에서 지금 당장 다룰 수 있는 가장 작은 항목을 고르고, 나머지는 목록에 남겨 둔다. 머릿속에 담아두지 않으니 지금 한 걸음에 집중할 수 있다.

판단 기준: 테스트 하나를 고르는 기준은 “가장 중요한 것”이 아니라 “지금 확실히 통과시킬 수 있는 가장 작은 것”이다. 함정: 첫 테스트부터 완벽한 API를 설계하려 들면 리듬이 시작되지 않는다. 테스트는 API의 초안이고, 초안은 고치면 된다.

한 사이클: 빨강 → 초록 → 리팩터링

아래 스텝 플레이어가 이 장의 전부다. 컴파일도 안 되는 테스트에서 시작해, 가짜 구현(죄악)으로 초록을 만들고, 중복을 지우며 진짜 구현에 도달한다.

Refactoring Step 빨강 — 실패하는 테스트를 먼저 쓴다
1/4
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장