컴퓨터 사이언스/소프트웨어 개발 방법론
[TDD] 기능 구현보다 테스트가 먼저다!
Dachaes
2025. 4. 14. 22:33
728x90
TDD(Test-Driven Development, 테스트 주도 개발)
TDD(Test-Driven Development)는 “테스트를 먼저 작성하고, 그 테스트를 통과하는 최소한의 코드를 작성한 뒤 리팩토링” 하는 개발 방식입니다. 처음에는 낯설게 느껴질 수 있지만, 코드의 안정성과 설계 품질을 향상시키는 데 매우 효과적인 접근입니다.
이 글에서는 TDD의 기본 개념, 3단계 사이클, 장단점, 그리고 실무에서의 적용 팁까지 정리해보겠습니다.
1. TDD란?
TDD(Test-Driven Development) 는 테스트 우선 접근 방식의 개발 프로세스입니다. 개발자는 기능을 구현하기 전에, 해당 기능이 어떻게 동작해야 하는지를 명확히 하기 위해 먼저 테스트 코드를 작성합니다.
핵심 사이클 : Red → Green → Refactor
단계 | 설명 |
Red | 실패하는 테스트 코드 작성 (아직 구현되지 않음) |
Green | 테스트가 통과할 수 있도록 최소한의 코드 구현 |
Refactor | 중복 제거, 구조 개선 등 리팩토링 (테스트는 계속 통과해야 함) |
왜 TDD를 사용하는가?
장점
- 요구사항을 명확히 이해하고 개발 가능
- 리팩토링이 수월해짐 (기존 기능이 망가지지 않았는지 테스트로 확인 가능)
- 디자인이 자연스럽게 모듈화/추상화됨
- 버그를 조기에 발견 가능
- 신뢰도 높은 코드 작성 가능
단점 / 현실적인 고려사항
- 초기에 시간이 더 걸리는 느낌
- 테스트 작성이 어려운 로직에서는 과도한 TDD가 생산성 저하로 이어질 수 있음
- 팀원 간의 테스트 품질 수준 차이 발생 가능
2. 예시 코드로 이해하는 TDD
자바스크립트와 Jest를 사용한 간단한 TDD 예시
Step 1 - 실패하는 테스트 먼저 작성 (Red)
// calculator.test.js
import { add } from './calculator';
test('1 + 2는 3이어야 한다', () => {
expect(add(1, 2)).toBe(3);
});
Step 2 - 테스트를 통과하는 최소한의 코드 (Green)
// calculator.js
export function add(a, b) {
return a + b;
}
Step 3 - 리팩토링 (필요한 경우)
- 코드 정리, 예외 처리 추가 등
3. 언제, 어디에 TDD를 적용하면 좋을까?
- 핵심 로직이 명확한 백엔드 서비스
- 계산 로직, 상태 변화 중심의 프론트엔드 컴포넌트
- 재사용이 많은 유틸 함수, 서비스 계층
반면, UI 디테일 중심의 화면 구성 등은 TDD보다는 테스트 후 구현이나 E2E 테스트가 더 적합할 수 있습니다.
4. TDD와 관련된 용어
용어 | 설명 |
단위 테스트(Unit Test) | 가장 작은 코드 단위(함수, 메서드)를 검증 |
테스트 커버리지 | 전체 코드 중 테스트로 검증되는 범위 |
Mocking | 외부 의존성을 가짜로 대체해 테스트 환경을 구성 |
BDD(Behavior-Driven Development) | 사용자 시나리오 중심 테스트, TDD의 확장 개념 |
a. 단위 테스트 (Unit Test)
- 단위 테스트는 프로그램에서 가장 작은 단위인 하나의 함수 또는 메서드 수준에서 그 기능이 올바르게 동작하는지 검증하는 테스트입니다.
- 일반적으로 외부 시스템(데이터베이스, 네트워크 등)과의 연동 없이, 독립적이고 빠르게 실행되는 것이 특징입니다.
- TDD에서 주로 작성하는 테스트 유형으로, 코드 품질을 일정 수준 이상으로 유지하는 데 매우 유용합니다.
b. 테스트 커버리지 (Test Coverage)
- 테스트 커버리지는 작성된 테스트가 전체 소스코드 중 얼마나 많은 부분을 실행하고 검증하는지를 나타내는 지표입니다.
- 보통 라인 커버리지, 브랜치 커버리지, 함수 커버리지 등으로 구분되며, 숫자가 높을수록 테스트가 코드 전반을 잘 검증하고 있음을 의미합니다.
- 단, 커버리지 비율이 높다고 해서 반드시 테스트의 품질이 높다는 의미는 아니므로, 적절한 테스트 설계와 함께 해석해야 합니다.
c. Mocking (모킹)
- 모킹은 테스트 중에 실제 외부 의존성(예: 데이터베이스, API 호출 등)을 가짜(mock) 객체로 대체하는 기법입니다.
- 이렇게 하면 테스트가 더 빠르고 안정적으로 동작할 수 있으며, 외부 환경에 의존하지 않고 일관된 테스트 결과를 얻을 수 있습니다.
- 예를 들어, 사용자 정보를 불러오는 API를 실제로 호출하지 않고, 미리 정의한 응답을 반환하도록 설정할 수 있습니다.
d. BDD (Behavior-Driven Development)
- BDD는 TDD에서 파생된 개념으로, 기능의 동작(Behavior) 을 중심으로 테스트를 설계합니다.
- 단위 테스트가 개발자의 시각이라면, BDD는 사용자 혹은 도메인 전문가의 시나리오를 바탕으로 테스트를 작성합니다. “주어진 상황에서, 어떤 동작을 했을 때, 이런 결과가 나와야 한다”는 Given–When–Then 형식을 자주 사용합니다.
- 대표적인 BDD 도구로는 Jest의 describe-it 패턴, Cucumber, Jasmine, Mocha 등이 있습니다.
5. 마무리
- TDD는 "테스트 → 구현 → 리팩토링" 의 반복을 통해 품질 높은 코드를 만드는 개발 방식입니다.
- 요구사항을 명확히 하면서 동시에 테스트 가능한 구조를 설계할 수 있도록 돕습니다.
- 상황에 맞게 현실적인 적용 범위를 정하는 것이 중요합니다.
함께 보면 좋은 자료
블로그 글 :
[워터폴과 애자일] 개발 프로젝트에 맞는 방법론은?
워터폴(Waterfall)과 애자일(Agile) 소프트웨어 개발 프로젝트를 시작할 때 가장 먼저 고려해야 할 것 중 하나는 어떤 개발 방법론을 선택할 것인가입니다. 그중에서도 가장 널리 알려진 두 가지 방
dachaes-devlogs.tistory.com
728x90