💡 핵심 인사이트
TDD(Test Driven Development)는 코드를 짜고 나서 그것이 잘 도는지 테스트하는 것이 아니라, 아예 **"실패하는 테스트 코드(정답지)를 먼저 작성하고, 그 테스트를 통과할 만큼의 실제 코드만 억지로 끼워 맞추듯 짜는 역발상 개발 방법론"**입니다.
처음엔 고통스럽지만, 완성된 코드는 수천 개의 든든한 테스트 방어막(안전망)을 가지게 되어 평생 버그 없는 리팩토링이 가능해집니다.


Ⅰ. 일반 개발 vs TDD의 순서 뒤집기

  • 전통적 개발 (Code First): 설계 ➔ 실제 기능 코딩 (300줄) ➔ 다 짠 뒤에 잘 돌아가나 테스트 (귀찮아서 대충 하거나 생략) ➔ 배포 후 버그 폭발.
  • TDD (Test First): "덧셈 함수는 1+1을 넣으면 2가 나와야 한다"라는 채점 로직(테스트 코드)부터 짭니다. 당연히 아직 실제 덧셈 함수 코드가 없으니 실행하면 에러(실패)가 납니다. 그다음에 이 에러를 없애기 위해 실제 함수 코드를 짭니다.

Ⅱ. TDD의 핵심 사이클 (Red - Green - Refactor)

TDD는 다음 3단계의 극단적으로 짧은 호흡(수 분 단위)을 무한 반복하는 수행 방식입니다.

1. RED (실패하는 테스트 작성)

  • 구현해야 할 기능의 명세(목표)를 코드로 작성합니다.
  • 예: assert_equal( calculator.add(1, 1), 2 )
  • 이때 calculator라는 클래스도 아직 안 만들었으므로 돌려보면 무조건 시뻘건 에러 창(Red)이 뜹니다.

2. GREEN (오직 테스트를 통과하기 위한 최단 코딩)

  • 빨간 에러 창을 초록색 성공(Green)으로 바꾸는 것이 유일한 목표입니다.
  • 디자인 패턴이나 멋진 코드는 개나 줘버리고, 가장 멍청한 방법이든 하드코딩이든 일단 테스트를 통과하게만 짭니다.
  • 예: function add(a, b) { return 2; } (1+1이 2니까 일단 무식하게 숫자 2를 리턴하게 짬 ➔ 초록불 뜸!)

3. REFACTOR (코드의 구조 개선)

  • 초록불이 뜬 것을 확인했으니, 이제 무식하게 하드코딩했던 코드를 예쁘고 객체지향적인 진짜 코드로 정리(Refactoring)합니다.
  • 예: function add(a, b) { return a + b; }
  • 코드를 고치다가 실수로 로직을 망가뜨려도 괜찮습니다. 1번에서 짜둔 강력한 테스트 코드가 즉시 Red를 띄워주어 내 실수를 실시간으로 알려주기(안전망) 때문입니다.

Ⅲ. TDD의 장점과 현실적인 한계 (왜 안 하는가?)

장점 (무적의 안전망)

TDD로 짠 수만 줄의 코드는 수천 개의 촘촘한 단위 테스트(Unit Test) 지뢰밭으로 둘러싸여 있습니다. 3년 뒤 신입사원이 들어와 핵심 로직을 뜯어고쳐도, 코드 한 줄 바꿀 때마다 수천 개의 테스트가 1초 만에 자동으로 싹 돌면서 부작용(사이드 이펙트)을 검사해 줍니다. 배포의 두려움이 완벽히 사라집니다.

단점 (진입 장벽)

  • 생산성 저하 (단기적): 실제 코드는 10줄인데, 그걸 검증하는 테스트 코드는 30줄을 짜야 합니다. 단기적인 개발 속도는 2배 이상 느려져 윗선(PM, PO)의 압박을 견디기 힘듭니다.
  • 러닝 커브: "테스트하기 쉬운 객체지향 설계(DI, Mocking 등)"에 대한 고도의 프로그래밍 지식이 없으면 TDD 자체를 시작조차 할 수 없습니다.

📢 섹션 요약 비유: 전통적인 코딩이 **"허허벌판에서 건물을 다 짓고 나서 마지막에 비계(안전망)를 설치하려는 위험한 공사"**라면, TDD는 바닥에 **"떨어져도 죽지 않는 튼튼한 그물망(Test)부터 촘촘히 쳐놓고, 그 위에서 안심하고 벽돌(Code)을 하나씩 쌓아 올리는 가장 안전한 건축법"**입니다.