TDD(Test-Driven Development)의 흐름과 장단점을 설명해주세요.
답변 포인트
Red, Green, Refactor 사이클을 중심으로 설명해보세요.
정답 및 해설
빠른 요약
TDD는 실패하는 테스트를 먼저 작성하고(Red), 테스트를 통과하는 최소 구현을 만든 뒤(Green), 테스트가 통과하는 상태에서 코드를 개선하는(Refactor) 개발 방식입니다. 장점은 요구사항을 검증 가능한 형태로 만들고, 테스트 가능한 설계를 유도하며, 리팩터링 안정감을 준다는 점입니다.
TDD는 테스트를 먼저 작성하고, 그 테스트를 통과하는 최소한의 코드를 구현한 뒤, 리팩터링하는 개발 방식입니다. 핵심 흐름은 Red, Green, Refactor입니다.
Red
먼저 실패하는 테스트를 작성합니다.
test("할인율을 적용한 가격을 계산한다", () => {
expect(calculateDiscountPrice(10000, 0.1)).toBe(9000);
});아직 calculateDiscountPrice가 없거나 구현되지 않았으므로 테스트는 실패합니다.
Green
테스트를 통과하는 최소한의 코드를 작성합니다.
function calculateDiscountPrice(price: number, rate: number) {
return price * (1 - rate);
}이 단계에서는 완벽한 설계보다 테스트를 통과시키는 것이 우선입니다.
Refactor
테스트가 통과하는 상태를 유지하면서 코드를 개선합니다.
function calculateDiscountPrice(price: number, rate: number) {
if (rate < 0 || rate > 1) {
throw new Error("할인율은 0과 1 사이여야 합니다.");
}
return Math.round(price * (1 - rate));
}추가 요구사항이 생기면 다시 실패하는 테스트부터 작성합니다.
TDD의 장점
- 요구사항을 코드로 명확히 표현할 수 있습니다.
- 테스트 가능한 설계를 유도합니다.
- 리팩터링에 대한 심리적 안정감을 줍니다.
- 과도한 구현을 줄이고 필요한 코드부터 작성하게 합니다.
- 버그 재현 테스트를 먼저 만들기 좋습니다.
TDD의 단점
- 초기 학습 비용이 있습니다.
- UI, 애니메이션, 외부 시스템 연동처럼 테스트 작성이 어려운 영역이 있습니다.
- 요구사항이 자주 바뀌면 테스트 수정 비용이 커질 수 있습니다.
- 잘못 작성한 테스트는 오히려 리팩터링을 방해합니다.
좋은 TDD를 위한 기준
구현 세부사항보다 외부에서 관찰 가능한 동작을 테스트해야 합니다.
// 좋지 않은 예: 내부 함수 호출 여부에 지나치게 의존
expect(repository.save).toHaveBeenCalledTimes(1);
// 더 나은 예: 결과 상태를 검증
expect(await repository.findByEmail(email)).toBeTruthy();모든 코드를 TDD로 작성해야 하는 것은 아닙니다. 복잡한 도메인 규칙, 계산 로직, 버그 수정, 라이브러리성 코드에 특히 효과적입니다.
정리
TDD는 테스트를 먼저 작성해 설계와 구현을 작은 단위로 진행하는 방식입니다. Red-Green-Refactor 흐름을 통해 요구사항을 검증 가능한 형태로 만들고, 리팩터링 가능한 코드를 유지하는 데 도움을 줍니다.
TDD의 기본 흐름
TDD는 테스트를 먼저 작성하고, 실패를 확인한 뒤, 최소 구현으로 통과시키고, 리팩터링하는 사이클입니다.
Red → Green → Refactor// Red: 원하는 동작을 먼저 표현
it('비밀번호가 8자 미만이면 실패한다', () => {
expect(validatePassword('abc')).toEqual({ ok: false, reason: 'too_short' });
});그다음 테스트를 통과시키는 가장 작은 구현을 작성하고, 중복과 이름을 정리합니다.
장점
- 요구사항을 실행 가능한 예제로 남길 수 있습니다.
- 과도한 설계를 줄이고 필요한 코드만 작성하게 됩니다.
- 리팩터링 시 회귀 버그를 빠르게 발견합니다.
한계
- UI의 시각적 품질이나 탐색적 설계에는 잘 맞지 않을 수 있습니다.
- 테스트하기 어려운 구조를 억지로 테스트하면 오히려 설계가 꼬일 수 있습니다.
- 팀이 테스트 품질 기준을 공유하지 않으면 깨지기 쉬운 테스트가 늘어납니다.
TDD는 모든 코드를 무조건 테스트 먼저 쓰라는 규칙보다, 불확실한 로직을 작은 피드백 루프로 검증하는 습관으로 이해하는 것이 좋습니다.