테스트 주도 개발(TDD)

[!tldr] 한줄 요약 테스트를 먼저 작성하고 통과시키는 Red-Green-Refactor 사이클로, 분 단위 피드백 루프를 통해 설계와 학습을 동시에 이끄는 개발 방법론이자 의도적 수련 방식이다.

핵심 내용

TDD란

켄트 벡(Kent Beck)이 1990년대 후반 익스트림 프로그래밍(XP)의 일부로 개발한 소프트웨어 개발 기법이다. 핵심 목표는 "작동하는 깨끗한 코드(Clean code that works)"로, 먼저 "작동하는(that works)" 문제를 해결한 뒤 "깨끗한 코드(clean code)" 문제를 해결한다.

단순한 테스트 기법이 아니라 설계 방법론에 가깝다. 테스트를 먼저 작성하면 코드의 사용 방식(인터페이스)을 먼저 고려하게 되어, 인터페이스와 구현을 효과적으로 분리하는 설계로 이어진다.

Red-Green-Refactor 사이클

TDD의 심장부는 세 단계의 반복이다:

단계행동핵심
Red실패하는 테스트 작성"무엇을 만들 것인가"를 정의
Green테스트를 통과시키는 최소한의 코드 작성깔끔하지 않아도 됨, 일단 통과
Refactor중복 제거, 구조 개선테스트가 여전히 통과하는지 확인하며 정리

마틴 파울러는 "TDD를 망치는 가장 흔한 방법은 세 번째 단계(Refactor)를 무시하는 것"이라고 경고한다. 이는 리팩토링(Refactoring)에서 다룬 "두 개의 모자" 개념과 직결된다 — Green 단계에서는 "기능 추가" 모자를, Refactor 단계에서는 "리팩토링" 모자를 쓴다.

피드백 루프로서의 TDD

피드백 루프(Feedback Loop)에서 배운 것처럼, 피드백 주기가 짧을수록 학습과 개선이 빨라진다. TDD는 분 단위의 피드백 루프를 제공한다:

TDD의 Red-Green-Refactor는 음성 피드백 루프(자기 교정 메커니즘)다. 버그 발견 → 수정 → 품질 회복의 순환으로, 시스템을 안정 상태로 수렴시킨다.

몰입을 유도하는 TDD

몰입(Flow)에서 배운 것처럼, TDD의 짧은 Red-Green 사이클은 몰입의 핵심 조건을 충족한다:

산만한 환경에서도 "코드 작성 → 테스트 통과"의 짧은 사이클은 몰입을 유도할 수 있다. 중단 시 실패하는 테스트를 남겨두면 복귀 시 맥락을 바로 잡을 수 있다.

TDD의 효과 — 연구 결과

김창준이 코칭한 프로젝트에서의 실험 결과:

김창준의 수파리(守破離) 수련법

김창준은 TDD 수련을 무술의 수파리에 비유한다. TDD는 단순한 기법이 아니라 의도적 수련(Deliberate Practice) 과정이다.

수(守) — 규칙을 충실히 지키기

파(破) — 규칙을 깨고 자기 방식 찾기

리(離) — 규칙에서 자유로워지기

초급자를 위한 조언

김창준은 첫 번째 테스트로 "아무것도 없는 상태(Empty)"를 잡는 것보다, 뭔가 있는 케이스를 먼저 잡고 전체를 가볍게 관통한 뒤 부분들을 키워나가는 방식을 권장한다. 핵심 경로(Happy Path)를 먼저 관통하는 것이다.

예시

[!example] Fake It 전략

# Red: 테스트 작성
def test_add():
    assert add(1, 2) == 3

# Green: 가짜로 통과
def add(a, b):
    return 3          # 하드코딩

# 다음 테스트 추가 → 일반화 강제
def test_add_different():
    assert add(3, 4) == 7

# Refactor: 진짜 구현
def add(a, b):
    return a + b

하드코딩 → 다음 테스트 → 일반화의 흐름이 GBC를 짧게 유지하고, "작은 성공의 반복"으로 몰입을 유도한다.

[!example] GBC 타이머 훈련

  1. 타이머를 5분으로 설정한다
  2. 테스트 통과(Green) 시점에 타이머를 리셋한다
  3. 타이머가 울리기 전에 다음 Green에 도달하지 못하면 롤백한다
  4. "왜 이 스텝이 너무 컸는가?"를 반성하고, 더 작은 단위로 쪼개서 재시도한다

참고 자료

관련 노트