테스트 주도 개발

테스트 주도 개발

켄트 벡의 TDD 원전을 장별로 따라가는 실전 노트. red → green → refactor 리듬을 diff로 기록한다.

켄트 벡의 『테스트 주도 개발』(Test-Driven Development: By Example)을 읽으며 장 단위로 정리합니다. 클린 코드가 “무엇이 좋은 코드인가”, 리팩터링이 “어떻게 거기로 가는가”였다면, 이 책은 “어떤 리듬으로 일하는가”입니다 — 실패하는 테스트를 먼저 쓰고, 어떻게든 통과시키고, 중복을 제거하는 반복.

책은 세 부로 구성됩니다.

  • 1부 화폐 예제 (1~17장) — 다중 통화 Money 객체를 TDD로 처음부터 끝까지 만든다. 책 전체의 백미. 매 장이 “테스트 추가 → 억지 통과 → 중복 제거”의 한 사이클이라, 노트에서는 각 장의 코드 변화를 스텝 플레이어의 diff로 따라간다.
  • 2부 xUnit 예제 (18~24장) — 테스트 프레임워크 자체를 TDD로 만든다. 자기 자신을 테스트하는 부트스트래핑.
  • 3부 테스트 주도 개발의 패턴 (25~32장) — 리듬을 지탱하는 패턴 카탈로그. 어떤 테스트를 먼저 쓸지, 얼마나 큰 걸음으로 갈지에 대한 답.

읽는 순서대로 장 노트가 아래 목차에 쌓입니다.

Contents

  1. 01
    1장 다중 통화를 지원하는 Money 객체첫 테스트를 쓰고, 컴파일만 되게 만들고, 죄악을 저질러 통과시키고, 중복을 제거한다. TDD의 한 사이클을 처음부터 끝까지 보여주는 장.
  2. 02
    2장 타락한 객체five.times(2)가 five 자신을 바꾸는 부작용을 없앤다. times가 새 Dollar를 반환하게 만들어 Money를 값 객체로 바꾸는 장.
  3. 03
    3장 모두를 위한 평등값이 같으면 같은 객체로 다루기 위해 equals()를 구현한다. 삼각측량으로 일반 해를 끌어내는 장.
  4. 04
    4장 프라이버시equals()가 생겼으니 테스트가 더 이상 amount를 직접 읽지 않아도 된다. 테스트를 개선해 amount를 private으로 감추는 장.
  5. 05
    5장 솔직히 말하자면두 번째 통화 Franc이 필요하다. Dollar를 통째로 복사-붙여넣기 하는 죄악을 알면서도 저지르고, 초록을 먼저 확보하는 장.
  6. 06
    6장 돌아온 '모두를 위한 평등'Dollar와 Franc의 중복을 없애기 위해 공통 상위 클래스 Money를 뽑고, 똑같던 equals를 한 곳으로 끌어올리는 장.
  7. 07
    7장 사과와 오렌지값만 같으면 Dollar와 Franc이 같다고 판정되는 버그를 테스트로 드러내고, getClass 비교로 통화가 다르면 다르다고 답하게 만드는 장.
  8. 08
    8장 객체 만들기팩토리 메서드 Money.dollar()/franc()로 생성을 감추고, times 선언을 Money로 끌어올려 클라이언트가 하위 클래스를 몰라도 되게 만드는 장.
  9. 09
    9장 우리가 사는 시간통화를 하위 클래스가 아니라 데이터로 표현한다. currency()를 도입하고 통화 문자열을 인스턴스 변수로 끌어올려, 하위 클래스를 없앨 발판을 만드는 장.
  10. 10
    10장 흥미로운 시간두 서브클래스의 times가 거의 같아졌다. equals를 통화 비교로 바꾸고, Money를 구상 클래스로 만들어 times를 위로 끌어올린다 — 서브클래스를 지우기 위한 준비 작업.
  11. 11
    11장 모든 악의 근원이제 아무 일도 하지 않는 Dollar와 Franc을 지운다. 팩터리가 new Money를 반환하게 바꾸고, 참조가 사라지면 서브클래스를 삭제한다. 상속을 걷어내는 리팩터링의 안전한 순서.
  12. 12
    12장 드디어, 더하기책 전체의 목표였던 더하기에 착수한다. $5 + $5부터. Expression 인터페이스와 Bank.reduce를 세우고, plus가 Sum을 반환하게 한다 — 아직 가짜 초록이지만 구조는 잡힌다.
  13. 13
    13장 진짜로 만들기가짜 상수를 걷어낸다. Bank.reduce가 식에게 환산을 위임하도록 Expression에 reduce를 추가하고, Sum과 Money가 각자 진짜 계산을 구현한다. 다형성으로 조건문을 없앤다.
  14. 14
    14장 바꾸기통화 변환을 넣는다. reduce가 Bank를 받아 환율로 나누도록 서명을 바꾸고, Bank.addRate와 Pair로 환율표를 만든다. 2프랑을 1달러로 환산하는 첫 진짜 변환.
  15. 15
    15장 서로 다른 통화 더하기책 첫 페이지의 목표 $5 + 10CHF = $10에 도달한다. 핵심은 Sum.reduce가 각 항을 목표 통화로 먼저 환산한 뒤 더하는 것. 식과 계산의 분리가 여기서 빛을 낸다.
  16. 16
    16장 드디어, 추상화식의 합도, 식의 곱도 다시 식이어야 한다. Expression에 plus와 times를 올리고 Sum이 이를 구현한다. Money와 Sum이 완전히 대칭이 되며 Expression 추상화가 닫힌다.
  17. 17
    17장 Money 회고1부 화폐 예제를 닫으며 되돌아본다. 메트릭, 걸음의 크기, 테스트가 설계를 이끈 방식. 코드 없이 프로세스를 성찰하고, 최종 설계 구조를 지도로 남긴다.
  18. 18
    18장 xUnit으로 가는 첫걸음테스트 프레임워크를 TDD로 만든다. 그런데 이 프레임워크를 테스트할 프레임워크가 아직 없다 — 부트스트래핑 딜레마를 수동 확인으로 뚫고 첫 TestCase와 WasRun을 세운다.
  19. 19
    19장 테이블 차리기매 테스트는 깨끗한 상태에서 시작해야 한다. setUp을 도입해 테스트 준비를 run 앞에 자동으로 끼워 넣고, 테스트 간 독립성을 뼈대로 못 박는다.
  20. 20
    20장 뒷정리하기tearDown으로 상을 치운다. 그리고 플래그 여러 개 대신 로그 문자열 하나로 호출 순서까지 검증한다 — Self Shunt로 이어질 아이디어의 원형.
  21. 21
    21장 셈하기테스트가 몇 개 돌았고 몇 개 실패했는지 사람이 알아야 한다. TestResult를 도입해 run/failed를 세고 '1 run, 0 failed'라는 요약을 돌려준다.
  22. 22
    22장 실패 처리하기테스트가 예외로 죽어도 프레임워크는 살아남아 '실패'로 기록해야 한다. try/except로 실패를 잡아 세고, 하드코딩이던 failed 카운트를 진짜로 만든다.
  23. 23
    23장 얼마나 달콤한지테스트를 하나씩 돌리는 건 지겹다. TestSuite로 여러 테스트를 묶어 한 번에 돌린다 — 개별 테스트와 묶음을 같은 방식으로 다루는 컴포지트 패턴.
  24. 24
    24장 xUnit 회고테스트할 프레임워크가 없는 채로 시작해, 스스로를 테스트하는 프레임워크에 도달했다. 부트스트래핑의 완성과 xUnit이 남긴 것을 돌아본다.
  25. 25
    25장 테스트 주도 개발 패턴무엇을 테스트하고 어떤 순서로 테스트할지에 대한 근본 패턴들. 테스트라는 명사의 정의부터 격리된 테스트, 테스트 목록, 테스트 우선, 단언 우선, 그리고 어떤 데이터를 쓸지까지.
  26. 26
    26장 빨간 막대 패턴실패하는 테스트를 언제, 어디서, 어떻게 쓸지에 대한 패턴들. 한 단계씩 나아가고, 어디서 시작하고, 배우기 위해 테스트를 쓰고, 막히면 버리고 쉬는 리듬까지.
  27. 27
    27장 테스팅 패턴테스트를 더 잘 쓰기 위한 기술적 패턴들. 큰 테스트를 쪼개는 자식 테스트, 협력 객체를 대신하는 모의 객체와 셀프 션트, 검증을 문자열로 모으는 로그 문자열, 그리고 일부러 깨 두는 테스트까지.
  28. 28
    28장 초록 막대 패턴실패하는 테스트를 통과시키는 세 가지 전략. 상수를 박는 가짜 구현, 예를 늘려 일반화를 유도하는 삼각측량, 그냥 바로 짜는 명백한 구현, 그리고 하나에서 여럿으로 나아가는 순서.
  29. 29
    29장 xUnit 패턴테스팅 프레임워크 자체를 이루는 구성 요소들. 결과를 검증하는 단언, 공통 준비를 담는 픽스처와 외부 픽스처, 테스트 메서드의 규약, 예외를 검증하는 법, 그리고 전체를 한 번에 돌리기.
  30. 30
    30장 디자인 패턴TDD를 하다 보면 반복해 만나는 GoF 계열 설계 패턴들. 커맨드·값 객체·널 객체·템플릿 메서드·플러거블 객체·팩토리 메서드·사칭 사기꾼·컴포지트·수집 매개 변수를 테스트 주도의 맥락에서 다시 읽는다.
  31. 31
    31장 리팩터링TDD의 초록 국면에서 쓰는 작은 리팩터링들. 두 코드의 차이를 좁히는 차이점 일치, 변화를 국소화하는 변화 격리와 데이터 이주, 그리고 메서드 추출·인라인·인터페이스 추출·메서드 옮기기.
  32. 32
    32장 TDD 마스터하기카탈로그를 닫는 마무리 장. 걸음 크기·피드백·테스트 삭제 기준·전환 비용 같은 실천의 조율 감각과, TDD가 디자인 패턴·XP와 맺는 관계를 짚으며 책을 닫는다.