개발지식

TDD란? (Test-Driven Development)

다오__ 2024. 3. 5. 16:15

https://www.youtube.com/watch?v=Npi21gLIEZM

유튜브 채널 드림코딩

 

TDD에 대해서 들어보기만 했었는데, 유튜브를 보고 웹프로젝트를 시작할 때 TDD를 따라 개발하려고 생각했었다.

 

 

아래는 GPT의 내용을 정리하였다.


TDD란?

TDD (Test-Driven Development)는 테스트 주도 개발 방법론으로, 소프트웨어 개발 과정에서 테스트를 먼저 작성하고, 이 테스트가 통과되도록 코드를 구현하는 방식입니다. TDD는 설계와 개발 과정에서 문제를 조기에 발견하고 해결하여, 코드의 품질을 향상시키는 데 도움을 줍니다. 스프링 프레임워크와 같은 Java 기반의 애플리케이션 개발에서 TDD를 적용하면, 코드의 안정성과 유지보수성을 높일 수 있습니다.

 

TDD의 기본 순서

  1. 실패하는 테스트 작성: 개발해야 할 기능에 대한 테스트 케이스를 먼저 작성합니다. 이 때, 테스트는 실패해야 합니다. 왜냐하면 구현할 기능이 아직 개발되지 않았기 때문입니다.
  2. 테스트를 통과하는 코드 작성: 작성한 테스트 케이스를 통과하기 위한 최소한의 코드를 작성합니다.
    리팩토링: 코드를 개선하고 최적화합니다. 이 과정에서 코드의 품질을 높이고, 유지보수가 용이하도록 합니다.

TDD 예시: 스프링 부트에서 회원 가입 기능 개발

  • 실패하는 테스트 작성 : 먼저, 사용자의 회원 가입 기능에 대한 테스트를 작성합니다. 이 예에서는 JUnit5와 Spring Boot Test를 사용하여 회원 가입 서비스의 테스트 코드를 작성합니다.
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
public class SignupServiceTest {

    @Autowired
    private SignupService signupService;

    @Test
    public void 회원가입_테스트() {
        // given
        User newUser = new User("username", "password");

        // when
        User registeredUser = signupService.register(newUser);

        // then
        assertThat(registeredUser.getUsername()).isEqualTo(newUser.getUsername());
    }
}

이 코드는 SignupService의 register 메소드를 테스트합니다. 아직 SignupService를 구현하지 않았기 때문에, 이 테스트는 실패할 것입니다.

 

  • 테스트를 통과하는 코드 작성 : 위 테스트를 통과하기 위한 SignupService 클래스와 필요한 로직을 구현합니다.
import org.springframework.stereotype.Service;

@Service
public class SignupService {

    public User register(User user) {
        // 여기에 회원 가입 로직 구현
        // 예를 들어, 데이터베이스에 사용자 정보를 저장하는 로직 등
        return user; // 임시 구현
    }
}

 

  • 리팩토링 : 테스트를 통과한 후에는 코드의 품질을 개선하고, 중복을 제거하는 등의 리팩토링 작업을 수행합니다. 예를 들어, 사용자 정보의 유효성 검사, 비밀번호 암호화, 예외 처리 로직을 추가할 수 있습니다.

 

TDD의 장점

  • 코드 품질 향상: 테스트를 먼저 작성하므로, 요구 사항을 충족하는 고품질의 코드를 개발할 수 있습니다.
  • 리팩토링 용이: 이미 테스트 케이스가 있기 때문에, 코드 구조를 개선하거나 기능을 변경할 때 안전하게 리팩토링할 수 있습니다.
  • 개발 효율성 증가: 초기에 문제를 발견하고 해결함으로써 장기적으로 보았을 때 개발 시간을 단축할 수 있습니다.
  • 문서화의 역할: 테스트 코드는 해당 기능이 어떻게 동작해야 하는지를 명시적으로 보여주므로, 문서의 역할도 수행합니다.

TDD의 지속적인 적용

  • 도메인 주도 설계(DDD)와의 결합: 도메인 모델을 중심으로 테스트 코드를 작성하면, 비즈니스 요구 사항을 보다 명확하게 반영할 수 있습니다.
  • 통합 테스트와의 결합: 단위 테스트뿐만 아니라 스프링 부트 애플리케이션의 컨트롤러, 서비스, 리포지토리 간의 상호작용을 검증하는 통합 테스트를 작성하여, 애플리케이션의 전체적인 동작을 보다 신뢰할 수 있게 만들 수 있습니다.
  • CI/CD 파이프라인과의 통합: 지속적인 통합(CI)과 지속적인 배포(CD) 파이프라인에 테스트를 통합함으로써, 코드 변경 사항이 기존 기능에 영향을 주지 않고, 새로운 기능이 기대대로 동작하는지 자동으로 검증할 수 있습니다.

TDD를 공부하면서 든 생각은, 오답노트를 기반으로 공부하는 느낌이 들었다. 어떤 문제에서 맞춘 개념, 부분은 패스하고 틀린부분에만 집중하면 효율적으로 학습하듯이,,