[Etc] TDD (Test-Driven Development, 테스트 주도 개발)

TDD (Test-Driven Development)에 대해 알아보자.


TDD (Test-Driven Development)란?

테스트 주도 개발

  • 소프트웨어 개발 방법론 중 하나로, 테스트 코드를 먼저 작성한 후 실제 기능을 구현하는 방식
    • 테스트 먼저, 코드 작성 나중!
  • 짧은 개발 주기의 반복에 의존하는 개발 프로세스
  • 애자일 방법론 중 하나인 eXtream Programming(XP)의 “Test-First” 개념에 기반을 둔 단순한 설계를 중요시함
    • eXtream Programming(XP)
      • 미래에 대한 예측을 최대한 하지 않고, 지속적으로 프로토타입을 완성하는 애자일 방법론 중 하나
      • 추가 요구사항이 생기더라도, 실시간으로 반영할 수 있음

TDD의 주요 과정

  • Red-Green-Refactor 세 단계 반복

1️⃣ Red (실패하는 테스트 작성)

  • 구현할 기능에 대한 테스트 코드 작성
  • 실제 기능이 이 시점에서는 없기 때문에 테스트는 실패
    • 빨간색 = 실패

2️⃣ Green (코드 작성 후 테스트 통과)

  • 테스트를 통과할 최소한의 코드만 작성
  • 코드가 정상적으로 동작하여 테스트가 성공하면 다음 단계로 넘어감
    • 초록색 = 성공

3️⃣ Refactor (리팩토링)

  • 코드의 중복을 제거하고 더 나은 구조로 개선
  • 테스트를 다시 실행하여 리팩토링 후에도 테스트가 성공하는지 확인
  • 성능 개선, 코드 가독성 높이기

TDD의 장점

  • 버그 감소
    • 미리 테스트를 작성하기 때문에 오류를 조기에 발견할 수 있음
  • 리팩토링 용이
    • 테스트 코드가 보장되므로 안심하고 코드를 사용 가능
  • 유지보수성 향상
    • 코드가 변경될 때 기존 기능이 정상적으로 동작하는지 확인 가능
  • 문서 역할
    • 테스트 코드 자체가 기능 명세서 역할을 함

TDD 예제 (Java)

1. 실패하는 테스트 작성

    import org.junit.jupiter.api.Test;
    import static org.junit.jupiter.api.Assertions.*;

    public class CalculatorTest {
        @Test
        void testAddition() {
            Calculator calc = new Calculator();
            assertEquals(5, calc.add(2,3));
        }
    }
  • 현재 Calculator 클래스와 add() 메서드가 없어서 테스트 실패

2. 최소한의 코드 작성 (테스트 통과)

    public class Calculator {
        public int add (int a, int b) {
            return a+b;
        }
    }
  • 이제 테스트 실행하면 성공!

3. 리팩토링

  • 코드가 복잡한 경우 성능 최적화나 코드 구조 개선 가능

TDD VS 전통적인 개발 방식

구분전통적인 개발 방식TDD
순서기능 구현 → 테스트 작성테스트 작성 → 기능 구현
목적기능 개발 후 버그 찾기처음부터 버그 방지
유지보수테스트 부족 시 리팩토링 어려움안전한 리팩토링 가능

TDD가 필요한 경우

  • 복잡한 로직이 포함된 코드
    • 알고리즘, 비즈니스 로직
  • 장기적으로 유지보수해야하는 프로젝트
  • 협업이 필요한 개발 환경
    • 테스트 코드가 문서 역할을 하므로 이해하기 쉬움

TDD의 단점

  • 간단한 코드에는 불필요한 오버헤드가 발생할 수 있음
  • 초기 개발 속도가 느려질 수 있음

xUnit

  • 단위 테스트를 위한 프레임워크
  • JUnit(for JAVA)을 시작으로 여러 xUnit 프레임워크가 탄생함
xUnit 이름해당 언어관련 사이트
CUnitCCUnit
CppUnitC++CppUnit
PHPUnitPHPPHPUnit
PyUnitPythonPyUnit
JUnitJavaJUnit