3.7 KiB
3.7 KiB
테스트 주도 개발 (TDD)
📌 Brief Summary
테스트 주도 개발(TDD)은 애자일 소프트웨어 개발에서 널리 사용되는 '테스트 우선(test-first)' 접근 방식이자 리팩토링의 토대가 되는 핵심 프랙티스이다 [1]. 이 방법론은 '실패하는 테스트 작성(Red)', '테스트를 통과하는 최소한의 코드 작성(Green)', '코드 구조 개선(Refactor)'이라는 세 가지 명확한 주기로 수행된다 [1-3]. TDD는 코드 변경 시 기존의 동작이 보존됨을 보장하며, 빠르고 안전한 리팩토링 루프를 형성하는 데 기여한다 [4, 5].
📖 Core Content
- Red-Green-Refactor 워크플로우: TDD 주기는 세 가지 명확한 단계로 구별된다. 첫째 'Red' 단계에서는 개발해야 할 내용을 확인하고 실패하는 테스트 코드를 작성한다. 둘째 'Green' 단계에서는 테스트를 통과할 수 있는 가장 단순한 코드를 작성한다. 셋째 'Refactor' 단계에서는 테스트가 통과(Green)하는 상태를 유지하면서 코드를 개선하고 향상시킨다 [1, 2]. 이 과정에서 새로운 기능 추가를 위한 코드 작성과 기존 코드를 리팩토링하는 작업은 절대로 동시에 수행되어서는 안 된다 [2].
- 설계 도구로서의 단위 테스트: 익스트림 프로그래밍(XP) 원칙에 뿌리를 둔 TDD를 통해 작성된 단위 테스트는 단순한 품질 보증 도구를 넘어 소프트웨어의 설계를 돕는 도구로 기능한다 [6]. 코드가 작성된 이후가 아니라 코드와 나란히, 혹은 그보다 먼저 테스트를 작성하게 되므로 피드백 루프가 극적으로 짧아진다 [3, 7].
- 리팩토링 안전망 역할: 성공적인 리팩토링 주기는 TDD 사이클과 매우 밀접하게 연관되어 있다 [5]. TDD는 아주 작은 변환을 적용한 후 즉시 모든 테스트를 다시 실행하여 성공 여부를 확인하게 하므로, 리팩토링이 시스템을 망가뜨리는 것을 방지하는 강력한 가드레일 역할을 수행한다 [5]. 만약 TDD와 지속적 통합(CI) 환경의 테스트를 실행하지 않고 리팩토링을 진행하면 새로운 버그를 유입시킬 위험이 매우 커진다 [8].
⚖️ Trade-offs & Caveats
- 사소한 코드 테스트로 인한 낭비 위험: TDD나 단위 테스트에 회의적인 입장의 개발자들은 100%의 테스트 커버리지를 달성하기 위해 Getter나 Setter와 같은 사소한 코드까지 테스트를 작성하도록 강요받는 상황을 문제 삼는다. 조건 논리가 포함되지 않은 단순한 구현을 맹목적으로 테스트하는 것은 실질적인 이득 없이 시간만 낭비하는 결과를 초래할 수 있다 [9, 10].
- 레거시 코드 적용의 딜레마: TDD의 원칙을 테스트가 없고 구조가 얽혀 있는 기존 시스템(레거시 코드)에 적용하려고 할 때 심각한 제약이 발생한다. 코드를 안전하게 리팩토링하려면 테스트가 필요하지만, 테스트를 작성하기 위해서는 먼저 코드를 변경하여 의존성을 끊어야 하는 역설적인 '레거시 코드의 딜레마'에 직면하게 된다 [11].
- 시간 제약 시의 우회적 접근: 촉박한 마감 시간으로 인해 방대한 레거시 클래스에 테스트를 작성할 여유가 없다면, 정석적인 TDD의 적용이 어려울 수 있다. 이러한 제약 상황에서는 기존 코드를 직접 건드리는 대신 'Sprout'나 'Wrap'과 같은 우회 기법을 사용하여 새로운 로직만을 별도의 위치에 작성 및 격리하고 이를 단위 테스트하는 차선책을 고려해야 한다 [12-14].
Last updated: 2026-05-03