Files
2nd/10_Wiki/Topics/Architecture/TDD (테스트 주도 개발).md
T

3.6 KiB

TDD (테스트 주도 개발)

📌 Brief Summary

TDD(테스트 주도 개발)는 설계 및 구현을 위해 '테스트 우선(test-first)' 접근 방식을 따르는 애자일 소프트웨어 개발 기법이다 [1]. 익스트림 프로그래밍(XP) 원칙에 뿌리를 두고 있으며, 기능 구현 전이나 구현과 동시에 단위 테스트를 작성한다 [2, 3]. 단위 테스트를 코드 작성 과정과 밀접하게 결합함으로써, TDD는 단순한 품질 보증 수단을 넘어 소프트웨어 설계를 위한 도구로 작용한다 [2]. 또한 실패하는 테스트 작성, 코드 구현, 리팩토링으로 이어지는 반복 주기를 통해 모든 형태의 리팩토링을 수행할 수 있는 기초를 제공한다 [1].

📖 Core Content

  • Red-Green-Refactor 워크플로우: TDD는 일반적으로 세 가지 명확한 단계로 수행된다.
    • RED: 실패하는 테스트(red-test)를 가장 먼저 작성하여 어떤 기능이 개발되어야 하는지 확인한다 [4, 5].
    • Green: 테스트를 통과할 수 있는 가장 단순한 수준의 코드를 작성하여 테스트를 성공(green)시킨다 [4, 5].
    • Refactor: 테스트가 통과하는 상태를 유지하면서 코드를 향상시키고 내부 구조를 개선한다 [4, 5]. 이 기법은 시스템에 새로운 기능을 추가하는 작업과 해당 기능을 리팩토링하는 작업을 동시에 수행하지 않도록 워크플로우를 분리해 준다 [4].
  • 안전한 리팩토링의 토대: TDD 및 지속적 통합(CI) 환경은 리팩토링 과정에서 필수적이다. 리팩토링 중에 작은 변경을 가한 후에는 반드시 테스트를 실행해야 하며, 이를 생략하면 새로운 버그가 유입될 위험이 커진다 [6, 7].
  • 레거시 코드와의 관계: TDD를 통해 테스트를 갖추지 못한 코드는 사실상 레거시 코드로 간주된다 [8]. 테스트라는 안전망 없이 대규모의 변경이나 리팩토링을 시도하는 것은 공중 곡예를 하는 것과 같이 매우 위험하므로, TDD를 통한 테스트 코드는 향후 코드 수정과 개선을 위한 필수 조건이 된다 [8].

⚖️ Trade-offs & Caveats

  • 불필요한 테스트 작성의 유혹과 비판: TDD에 반대하는 사람들은 100%의 테스트 커버리지를 달성하기 위해 gettersetter처럼 조건 논리조차 없는 사소한 코드까지 테스트해야 한다고 비판하며 이를 무의미한 작업으로 치부하기도 한다 [9]. 하지만 실제로는 명백하게 단순한 구현부는 테스트하지 않는 것이 권장되며, 모든 것을 테스트하려는 강박은 오히려 시간 낭비를 초래할 수 있다 [10].
  • 테스트 유지보수 부채: TDD로 작성된 테스트 코드 역시 제품 코드와 동일하게 취급되어 정기적인 유지보수와 리팩토링이 필요하다 [11, 12]. 테스트 코드의 품질을 관리하지 않으면 테스트 스위트가 점점 느려지고 깨지기 쉬워지며(brittle), 결과적으로 리팩토링을 방해하는 부채가 될 수 있다 [13, 14].
  • 도입 딜레마 (레거시 코드 환경): 기존 시스템이 TDD로 작성되지 않은 경우, 테스트를 추가하려면 강하게 결합된 의존성을 끊기 위해 코드를 먼저 변경해야 한다 [15, 16]. 그러나 안전하게 코드를 변경하려면 사전에 테스트가 존재해야 한다는 모순적인 '레거시 코드의 딜레마'에 빠지게 되어, 이를 해결하기 위한 상당한 비용과 노력이 수반된다 [15].

Last updated: 2026-05-03