테스트 주도 개발이 강제하는 설계의 우아함

문제의식

많은 개발자가 “설계는 경험과 직관의 문제”라고 말한다. 하지만 TDD는 설계를 강제한다. 이는 단순한 방법론 이상의 의미를 가진다.

핵심 통찰

테스트 가능성 = 설계 품질

TDD를 적용하려면 코드가 테스트 가능해야 한다. 이는 자연스럽게 다음과 같은 설계 원칙을 강제한다:

  1. 의존성 주입: 테스트에서 mock이나 stub을 주입하려면 의존성이 명시적으로 드러나야 한다.
  2. 단일 책임 원칙: 테스트하기 쉬운 코드는 하나의 책임만 가진다.
  3. 인터페이스 분리: 구체적인 구현보다 추상화에 의존하게 된다.

역발상: 테스트가 설계를 주도한다

일반적인 개발 순서: 요구사항 → 설계 → 구현 → 테스트

TDD의 순서: 요구사항 → 테스트(설계의 첫 형태) → 구현 → 리팩토링(설계 개선)

여기서 테스트는 단순한 검증 도구가 아니라, 설계의 첫 번째 초안이다. 테스트를 작성하는 과정에서 이미 모듈의 인터페이스, 책임, 협력 관계가 결정된다.

실제 사례

필자가 경험한 사례: 복잡한 결제 시스템을 TDD로 개발할 때, 테스트를 먼저 작성하면서 자연스럽게 결제 게이트웨이를 추상화하게 되었다. 결과적으로 다양한 결제 수단을 쉽게 추가할 수 있는 유연한 설계가 완성되었다.

참고