[테스트전략] 테스트 수행 시간을 줄이기 위한 환경 통합

y001·2025년 1월 27일
post-thumbnail

1. 도입: 스프링 부트가 뜨는 조건과 배경

스프링 부트 애플리케이션은 테스트 환경 설정에 따라 새로 기동됩니다. 동일한 설정에서는 애플리케이션 컨텍스트를 재사용하지만, 아래와 같은 조건이 달라지면 새로운 컨텍스트가 생성됩니다:

  • Active Profiles 차이: 서로 다른 프로파일(@ActiveProfiles)이 설정된 경우.
  • Mock 처리한 빈 차이: @MockBean 또는 @MockMvc 설정이 다를 경우.
  • 테스트 방식 차이: @SpringBootTest, @WebMvcTest 등 사용된 테스트 어노테이션이 다를 경우.

이로 인해 서버가 반복적으로 기동되면서 테스트 수행 시간이 길어질 수 있습니다. 이를 방지하려면 환경을 통합하여 컨텍스트 재사용성을 높이는 전략이 필요합니다.


2. 문제와 해결책

문제점

테스트 환경이 분리될 경우 발생하는 주요 문제는 다음과 같습니다:

  • 반복적인 애플리케이션 기동: 테스트마다 애플리케이션 컨텍스트가 새로 생성되어 리소스가 낭비됩니다.
  • 긴 테스트 시간: 환경 설정의 차이로 인해 테스트 수행 시간이 증가합니다.
  • 비효율적 테스트 수행: 서버 기동 횟수가 늘어나면서 테스트가 비효율적으로 진행됩니다.

해결책

  • 환경 통합: IntegrationTestSupport와 ControllerTestSupport를 활용해 공통 환경을 구성합니다.
  • 서버 기동 최소화: 동일한 환경에서 테스트를 수행하여 서버 재기동 횟수를 줄입니다.

3. 서버 기동 문제 해결 전략

문제 상황 분석

테스트 실행 시 스프링 부트가 여러 번 기동되면 전체 테스트 수행 시간이 불필요하게 길어집니다. 아래는 실제 로그 예시입니다: 이미지에서 볼 수 있듯이 테스트 전체 수행 시 Spring Boot 기동 횟수가 6회입니다.

서버가 여러 번 기동되면 리소스 낭비뿐만 아니라 테스트 속도도 저하됩니다. 이를 해결하기 위해 공통 환경을 통합해야 합니다.


4. 환경 통합 코드 구현

(1) Service/Repository 테스트 환경 통합

Service와 Repository 테스트를 위한 공통 설정 클래스를 정의하여 중복된 환경 설정을 제거합니다.

@ActiveProfiles("test")
@SpringBootTest
public abstract class IntegrationTestSupport {
    // 공통 테스트 환경 설정
}

class MailServiceTest extends IntegrationTestSupport {
    @Test
    void testSendMail() {
        // MailService 관련 테스트 코드
    }
}

(2) Controller 테스트 환경 통합

Controller 테스트를 위한 공통 설정 클래스를 정의하여 MockMvc와 MockBean을 통합적으로 관리합니다.

@WebMvcTest(controllers = {
        OrderController.class,
        ProductController.class
})
public abstract class ControllerTestSupport {

    @Autowired
    protected MockMvc mockMvc;

    @Autowired
    protected ObjectMapper objectMapper;

    @MockBean
    protected OrderService orderService;

    @MockBean
    protected ProductService productService;
}

class ProductControllerTest extends ControllerTestSupport {
    @Test
    void testCreateProduct() throws Exception {
        mockMvc.perform(post("/products")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"name\":\"Coffee\",\"price\":5000}"))
                .andExpect(status().isOk());
    }
}

위 설정을 통해 반복적인 환경 설정을 제거하고, 컨텍스트 재사용성을 극대화할 수 있습니다.

5. 결과

테스트 수행 시간 단축 결과

  • 수행 시간: 3,127ms
  • 서버 기동 횟수: 3회

실제 사이드 프로젝트를 진행하면서 CICD를 구축할 때, 모든 테스트를 통과해야만 변경사항이 main 브랜치에 적용되도록 구성했습니다. 이때 문제 중 하나가 test (Build) 시간이 점차 길어진다는 것이었습니다. 빠른 변경사항 적용과 배포를 위해 이러한 테스트 환경 통합을 이용할 수 있을 거라는 생각이 들었습니다. 다음에는 이를 활용해서 테스트 환경을 개선해보겠습니다.


📌 이 글은 TDD 강의를 학습한 내용을 바탕으로 재구성하였습니다. 문제가 되는 부분이 있다면 수정하겠습니다.

0개의 댓글