기록

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

교육/강의

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

youngyin 2025. 2. 11. 00:00

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) 시간이 점차 길어진다는 것이었습니다. 빠른 변경사항 적용과 배포를 위해 이러한 테스트 환경 통합을 이용할수 있을거라는 생각이 들었습니다. 다음에는 이를 활용해서 테스트 환경을 개선해보겠습니다.

Comments