TDD (Test Driven Development, 테스트 주도 개발)
개발 프로세스에서 테스트를 먼저 작성한 후 그 테스트를 통과하는 코드를 작성하는 방식
기본 개념
다음 3단계의 사이클을 반복한다
1. Red (실패)
- 실패하는 테스트 코드를 작성한다
- 새로운 기능이나 요구사항이 반영되지 않은 상태에서 테스트가 실패해야 한다
2. Green (성공)
- 테스트를 통과할 최소한의 코드를 작성한다
- 구현은 간단해야 하며, 테스트를 통과하는 것에만 집중한다
3. Refactor (리팩토링)
- 테스트를 통과한 코드를 리팩토링하여 품질을 개선
- 중복코드 제거, 성능 최적화, 가독성 향상 등 코드의 구조를 개선한다
- 테스트가 다시 실패하지 않음을 확인
TDD의 목표
- 코드 품질을 높이고 버그 발생 가능성 줄이기
- 작고 검증 가능한 단계로 개발하여 복잡한 문제를 해결하기 쉽게 만듦
- 자동화된 테스트를 통해 지속적인 변경에도 안정성을 유지
장점
- 품질 높은 코드 작성
- 명확한 테스트를 작성하며 설계 단계에서 요구사항을 구체화합니다.
- 깨지기 쉬운 코드가 줄어듭니다.
- 리팩터링의 자신감 증가
- 기존 코드에 대한 테스트가 있으므로, 기능이 깨지지 않음을 보장하면서 리팩터링할 수 있습니다.
- 디버깅 시간 단축
- 테스트를 통해 문제를 조기에 발견할 수 있습니다.
- 작은 단위의 개발과 통합
- 테스트 단위가 작으므로 개발 프로세스를 작은 단계로 나눌 수 있습니다.
- 문서화의 대체 가능
- 테스트 코드는 동작 방식을 명확히 나타내므로, 일종의 실행 가능한 문서 역할을 합니다.
단점
- 초기 개발 속도 저하
- 테스트를 먼저 작성해야 하므로 초기 속도가 느릴 수 있습니다.
- 테스트 작성의 어려움
- 경험이 부족한 개발자는 좋은 테스트 케이스를 작성하기 어렵습니다.
- 모든 상황에 적합하지 않음
- GUI와 같은 비즈니스 로직이 없는 코드에는 적용하기 어렵습니다.
- 데이터베이스, 네트워크와 같이 외부 종속성이 큰 시스템에서는 복잡해질 수 있습니다.
TDD 사이클 예제
요구사항: 숫자를 입력받아 짝수인지 확인하는 메소드를 작성한다.
1. Red 단계 (테스트 작성)
실패하는 테스트를 작성:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class NumberUtilsTest {
@Test
void testIsEven() {
assertTrue(NumberUtils.isEven(2)); // 2는 짝수
assertFalse(NumberUtils.isEven(3)); // 3은 홀수
}
}
2. Green 단계 (코드 작성)
테스트를 통과하는 최소한의 코드 작성:
public class NumberUtils {
public static boolean isEven(int number) {
return number % 2 == 0;
}
}
3. Refactor 단계 (리팩토링)
현재 코드는 간단하므로 추가 리팩터링은 필요하지 않음.
TDD 도구
- JUNIT : 자바에서 가장 널리 사용되는 테스트 프레임워크
- Mockito : Mock 객체 생성 및 테스트를 지원하는 라이브러리
- TestNG : JUnit의 대안으로 더 많은 기능을 제공
- Hamcrest : 가독성이 높은 매처(Matcher)를 제공
TDD 적용 시 주의사항
- 테스트의 단위
- 테스트는 작은 단위로 작성해야 하며, 하나의 테스트는 하나의 기능만 검증해야 합니다.
- 테스트 독립성
- 각 테스트는 서로 독립적이어야 하며, 실행 순서에 영향을 받지 않아야 합니다.
- 테스트 유지보수
- 변경된 요구사항에 따라 테스트도 지속적으로 업데이트해야 합니다.
- 테스트 범위 설정
- TDD는 모든 코드를 테스트하는 것이 아니라 핵심 비즈니스 로직과 복잡한 부분에 집중해야 합니다.
TDD를 적용한 워크플로우
- 요구사항 분석 및 테스트 시나리오 작성
- Red: 실패하는 테스트 작성
- Green: 테스트 통과를 위한 최소한의 코드 작성
- Refactor: 리팩터링 및 테스트 유지보수
- 반복 (기능 확장 및 개선)
출처 : ChatGPT