CS 지식

TDD

이제하네 2024. 9. 23. 20:36

1. TDD의 정의

TDD(Test-Driven Development, 테스트 주도 개발)는 테스트를 먼저 작성하고, 그 테스트를 통과할 수 있는 최소한의 코드를 구현하는 개발 방법론입니다. 즉, 코드를 작성하기 전에 먼저 해당 코드가 정확히 동작하는지를 확인할 수 있는 테스트를 먼저 작성하는 것입니다.

TDD의 핵심 단계:

  1. 테스트 작성: 아직 구현되지 않은 기능에 대해 실패할 테스트 코드를 작성합니다.
  2. 구현: 해당 테스트를 통과할 수 있을 정도로 최소한의 코드를 작성합니다.
  3. 리팩토링: 테스트가 통과한 후, 코드를 개선하거나 최적화합니다.

2. TDD의 장점

  • 빠른 피드백: 테스트를 먼저 작성함으로써 코드 작성 후 바로 테스트가 가능합니다. 이를 통해 오류를 빠르게 발견할 수 있습니다.
  • 디자인 개선: TDD는 자연스럽게 모듈화된 설계를 유도하여 깨끗하고 유지보수가 쉬운 코드를 작성할 수 있습니다.
  • 자신감 향상: 기능 구현 후 테스트를 통과하는지 즉시 확인할 수 있기 때문에 코드 품질에 대한 신뢰도가 높아집니다.
  • 디버깅 시간 단축: 코드에서 발생하는 문제를 빠르게 확인하고 해결할 수 있어 디버깅 시간을 줄여줍니다.

3. TDD의 기본 절차

TDD는 레드-그린-리팩토링(Red-Green-Refactor)의 세 가지 단계를 따릅니다.

  1. Red: 실패하는 테스트 작성
    • 코드가 없는 상태에서 먼저 테스트를 작성하고, 당연히 이 테스트는 실패합니다.
  2. Green: 테스트 통과를 위한 최소한의 코드 작성
    • 테스트를 통과하기 위한 가장 단순한 코드를 작성합니다. 이때는 코드의 최적화보다는 테스트를 통과하는 데에만 집중합니다.
  3. Refactor: 리팩토링
    • 코드를 개선하여 중복을 제거하거나 가독성을 높이고, 구조를 개선합니다. 이 과정에서도 기존 테스트가 통과하는지 확인합니다.

4. TDD의 예시: 자바로 구현한 간단한 예제

TDD의 과정을 간단한 자바 예제와 함께 살펴보겠습니다. 여기서는 간단한 계산기(Calculator) 프로그램을 구현해 보겠습니다.

4.1. 1단계: 실패하는 테스트 작성 (Red)

먼저, add() 메서드를 테스트하는 코드를 작성합니다. 이 메서드는 두 수를 더한 값을 반환하는 역할을 합니다. 하지만 아직 구현이 되어 있지 않기 때문에 테스트는 실패할 것입니다.

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class CalculatorTest {

    @Test
    public void testAdd() {
        Calculator calculator = new Calculator();
        int result = calculator.add(2, 3);
        assertEquals(5, result);  // 2 + 3 = 5를 기대
    }
}

이 단계에서 Calculator 클래스와 add() 메서드는 아직 구현되지 않았기 때문에 컴파일 오류가 발생할 것입니다.

4.2. 2단계: 테스트 통과를 위한 코드 작성 (Green)

이제 테스트를 통과할 수 있는 최소한의 코드를 작성합니다. 이 코드는 테스트에서 요구하는 기능만을 구현하며, 가능한 한 단순하게 작성합니다.

public class Calculator {

    public int add(int a, int b) {
        return a + b;  // 두 수를 더하는 기능 구현
    }
}
 

이제 테스트를 실행하면 add() 메서드가 두 수를 더한 값을 올바르게 반환하기 때문에 테스트는 통과할 것입니다.

4.3. 3단계: 리팩토링 (Refactor)

테스트가 통과했으므로 코드를 개선할 수 있는지 살펴봅니다. 이 예제에서는 코드가 매우 간단하므로 리팩토링할 부분이 별로 없지만, 만약 코드가 더 복잡해졌다면 중복된 부분을 제거하거나, 가독성을 높이는 리팩토링 작업을 할 수 있습니다.

public class Calculator {

    // 현재의 간단한 코드에서는 특별한 리팩토링이 필요하지 않음
    public int add(int a, int b) {
        return a + b;
    }
}
 

추가 테스트: 다른 기능 추가하기

계산기 프로그램에 새로운 기능을 추가하고 싶다면, 예를 들어 곱셈 기능을 추가하는 과정을 살펴보겠습니다. 먼저 실패하는 테스트를 작성하고, 그런 후에 해당 기능을 구현하는 방식으로 TDD를 적용할 수 있습니다.

@Test
public void testMultiply() {
    Calculator calculator = new Calculator();
    int result = calculator.multiply(2, 3);
    assertEquals(6, result);  // 2 * 3 = 6을 기대
}
 

그리고 곱셈 기능을 구현합니다.

public class Calculator {

    public int add(int a, int b) {
        return a + b;
    }

    public int multiply(int a, int b) {
        return a * b;
    }
}

이렇게 새로운 기능을 추가할 때마다 TDD 방식으로 테스트를 먼저 작성한 후 해당 기능을 구현하는 방식으로 개발을 진행할 수 있습니다.

5. TDD의 실제 적용 시 고려 사항

  • 작은 단위 테스트 작성: TDD에서는 작은 단위의 기능을 먼저 테스트하고 구현하는 것이 중요합니다. 큰 기능을 한 번에 구현하지 말고, 각 기능을 작은 테스트로 분리하세요.
  • 빈번한 테스트 실행: TDD에서는 테스트를 자주 실행하여 코드가 제대로 동작하는지 자주 확인해야 합니다. 새로운 기능을 추가하거나 코드를 수정할 때마다 테스트를 실행합니다.
  • 리팩토링: 테스트가 통과할 때마다 코드를 개선하거나 구조를 최적화하는 작업을 통해 품질을 유지해야 합니다.

'CS 지식' 카테고리의 다른 글

스프링과 스프링부트의 차이점  (0) 2024.09.23
예외처리  (2) 2024.09.08
동기 ,비동기 처리  (0) 2024.09.02
SOLID 원칙  (0) 2024.09.01
추상 클래스와 인터페이스  (0) 2024.08.25