테스트 주도 개발 (TDD, Test Driven Development)
한눈에 보기
TDD는 실패하는 테스트를 먼저 작성하고 이를 통과시키는 최소한의 코드를 만든 뒤 다듬는 과정을 반복하는 개발 방법이다. 레드 그린 리팩터 사이클, 설계 효과, 장단점과 실무 함정을 정리한다.
최종 업데이트 2026.09.17
테스트 주도 개발(Test Driven Development, TDD)은 구현 코드를 작성하기 전에 실패하는 테스트를 먼저 작성하고, 그 테스트를 통과시키는 최소한의 코드를 만든 뒤 구조를 다듬는 과정을 짧게 반복하는 개발 방법이다. 테스트 주도 개발의 핵심은 테스트 자체보다 설계에 있으며, 코드를 사용하는 쪽의 관점에서 먼저 생각하게 만들어 테스트하기 쉬운 구조, 곧 결합도가 낮은 설계를 자연스럽게 유도한다. 켄트 벡(Kent Beck)이 익스트림 프로그래밍의 실천법으로 정립했다.
레드 그린 리팩터 사이클
TDD는 세 단계를 수 분 단위로 반복한다.
- 레드(Red): 아직 없는 기능에 대한 테스트를 먼저 작성하고 실행해서 실패를 확인한다. 실패를 눈으로 확인하는 단계가 중요하다. 처음부터 통과하는 테스트는 아무것도 검증하지 못하는 테스트일 수 있기 때문이다.
- 그린(Green): 테스트를 통과시키는 가장 단순한 코드를 작성한다. 이 단계에서는 코드의 아름다움을 따지지 않고 통과 자체에 집중한다. 심지어 값을 하드코딩해서라도 일단 초록 막대를 만든 뒤, 다음 테스트가 그 꼼수를 무너뜨리게 하는 전략도 정석으로 인정된다.
- 리팩터(Refactor): 테스트가 통과하는 상태를 유지하면서 중복을 제거하고 이름과 구조를 다듬는다. 테스트가 안전망이 되어 주므로 과감하게 정리할 수 있다.
간단한 예로 할인 계산기를 TDD로 시작하면 다음과 같다.
// 1. Red: 구현이 없으므로 실패한다
test("10만원 이상 구매 시 10% 할인", () => {
expect(discountedPrice(100000)).toBe(90000);
});
// 2. Green: 통과하는 최소 구현
function discountedPrice(amount) {
if (amount >= 100000) return amount * 0.9;
return amount;
}
// 3. 다음 Red: 경계와 새 규칙을 테스트로 추가하며 반복
test("10만원 미만은 할인이 없다", () => {
expect(discountedPrice(99999)).toBe(99999);
});
이 리듬을 유지하면 요구사항이 실행 가능한 명세로 하나씩 쌓이고, 모든 코드는 자신을 검증하는 테스트를 가진 채 태어난다. 한 사이클을 몇 분 안에 끝낼 수 있을 만큼 걸음을 작게 유지하는 것이 핵심 기술이며, 막히면 더 작은 걸음으로 쪼개는 것이 정석이다.
TDD가 주는 것: 테스트가 아니라 설계
TDD의 가장 큰 효과는 회귀 버그 방지 그 이상이다. 테스트를 먼저 쓰려면 코드를 호출하는 입장이 되어야 하므로, 사용하기 불편한 인터페이스가 구현 전에 드러난다. 또 테스트하기 어려운 코드는 대개 의존성이 얽힌 코드다. 데이터베이스, 시간, 네트워크에 직접 의존하는 로직은 테스트가 고통스럽기 때문에, TDD를 하다 보면 의존성을 주입받는 구조와 순수한 핵심 로직의 분리가 강제된다. 즉 테스트 용이성은 좋은 설계의 훌륭한 근사 지표이며, 테스트를 쓰기가 괴롭다면 테스트가 아니라 설계를 의심하라는 조언이 여기서 나온다. 그 밖의 효과로는 언제든 돌릴 수 있는 회귀 테스트 묶음, 문서보다 정확한 사용 예시, 그리고 작은 단위로 완결을 확인하며 나아가는 심리적 안정감이 있다.
장점과 비용
| 구분 | 내용 |
|---|---|
| 장점 | 결함을 이른 시점에 발견, 리팩토링을 위한 안전망 확보, 결합도 낮은 설계 유도, 요구사항의 실행 가능한 문서화, 디버깅 시간 감소 |
| 비용 | 초기 개발 속도 저하 체감, 학습 곡선, 테스트 코드도 유지보수 대상, UI나 탐색적 프로토타입 등 사전 명세가 어려운 영역과의 부조화 |
연구와 현장 경험을 종합하면 TDD는 코드 작성 시간을 다소 늘리는 대신 결함 밀도를 낮추고, 프로젝트가 길어질수록 총비용에서 이득을 보는 경향이 있다. 반대로 요구사항이 극도로 유동적인 실험 코드나 곧 버릴 프로토타입에는 투자 대비 효과가 낮다. 테스트가 없는 레거시 코드에 새 기능을 넣어야 할 때는, 수정할 부분의 현재 동작을 고정하는 테스트를 먼저 확보한 뒤 그 위에서 TDD를 시작하는 절충이 현실적이다.
진행 방향: 안에서 밖으로, 밖에서 안으로
TDD를 진행하는 방향에는 두 학파가 있다. 고전파(Classicist)로도 불리는 안에서 밖으로(Inside-Out) 방식은 도메인의 핵심 로직부터 실제 객체로 테스트하며 바깥 계층으로 확장해 나가고, 런던파(London School)로 불리는 밖에서 안으로(Outside-In) 방식은 사용자에게 가까운 바깥 계층에서 시작해 아직 없는 협력 객체를 목으로 대체하며 안쪽 설계를 이끌어 낸다. 전자는 리팩토링에 강한 테스트를 만들고, 후자는 객체 간 협력 구조를 먼저 그리게 해 준다. 실무에서는 실패하는 인수 테스트를 바깥에 하나 걸어 두고 이를 통과시키기 위해 안쪽에서 단위 TDD 사이클을 도는 이중 루프(Double Loop) 형태로 두 접근을 결합하는 경우가 많다.
실무 적용 지침과 흔한 함정
단위 테스트(Unit Test)를 촘촘히 깔고 통합 테스트(Integration Test)와 엔드 투 엔드 테스트(End-to-End Test)를 위로 갈수록 적게 두는 테스트 피라미드(Test Pyramid)가 기본 전략이다. 외부 의존성은 테스트 더블(Test Double), 즉 스텁(Stub)이나 목(Mock)으로 대체하되, 목을 남용해 테스트가 구현의 내부 호출 순서까지 검증하게 만들면 리팩토링만 해도 테스트가 깨지는 취약한 테스트가 된다. 테스트는 구현이 아니라 관찰 가능한 동작을 검증해야 한다. 각 테스트는 준비, 실행, 검증의 3단계(Given-When-Then)로 구성하고 하나의 동작만 검증하며, 이름만 읽어도 어떤 요구사항인지 드러나게 짓는다. 커버리지 수치를 목표로 삼는 것도 함정이다. 커버리지는 테스트되지 않은 곳을 찾는 도구일 뿐, 높은 수치가 좋은 테스트를 보장하지 않는다. 파생 방법론으로는 테스트를 "구매자가 상품을 담으면 재고가 줄어든다"처럼 행위 명세 형식으로 쓰는 행위 주도 개발(Behavior Driven Development, BDD)이 있으며, 비개발 이해관계자와의 소통 도구로 확장된 형태다.
면접에서 이렇게 물어본다
- TDD의 레드 그린 리팩터 사이클을 설명하고, 실패하는 테스트를 먼저 확인하는 이유를 말해 보라.
- TDD가 설계 품질을 높인다고 말하는 근거는 무엇인가.
- 목 객체를 과도하게 사용할 때 생기는 문제를 설명해 보라.
- 테스트 피라미드가 무엇이며 왜 단위 테스트의 비중을 높게 가져가는가.
- TDD를 적용하기 어려운 상황과 그때의 대안을 말해 보라.
소프트웨어 공학에서 같이 읽기
- 애자일 (Agile)애자일은 2001년 애자일 소프트웨어 개발 선언에 뿌리를 둔 개발 철학으로, 계획과 문서보다 동작하는 소프트웨어와 협력을 앞세운다. 네 가지 가치와 열두 원칙, 폭포수 모델과의 차이, 흔한 오해까지 정리한다.
- 애자일 방법론: 스크럼과 칸반 (Scrum and Kanban)애자일 철학을 실천하는 대표 방법론인 스크럼과 칸반을 다룬다. 스크럼의 역할, 이벤트, 산출물과 칸반의 WIP 제한, 두 방식의 비교와 실무 적용 시 주의점을 정리한다.
- 클린 코드와 리팩토링 (Clean Code and Refactoring)클린 코드는 읽고 수정하기 쉬운 코드, 리팩토링은 동작을 바꾸지 않고 구조를 개선하는 활동이다. 코드 스멜, 대표 리팩토링 기법, 테스트 안전망을 갖춘 안전한 절차와 판단 기준을 정리한다.
- 클린 코드와 시큐어 코딩 (Secure Coding)시큐어 코딩은 구현 단계부터 보안 취약점을 막는 방법론이다. 모든 입력을 신뢰하지 않는다는 원칙, SQL 삽입과 XSS 방어, OWASP 기준 취약점 대응과 클린 코드가 보안을 돕는 이유를 정리한다.
이 개념, 내 코드에서는 어떻게 물어볼까요
데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.
공고 넣고 시작하기