티스토리 뷰
스프링 부트가 제공하는 테스트는 모두 통합 테스트입니다. 그러다보니 스프링부트 설정이나 테스트 코드를 작성할 때 주의해야 하는 부분들이 있습니다. 이번에는 테스트가 느려지지 않도록 하는 주의사항에 대해 살펴보겠습니다.
1. 스프링 부트 설정 시의 주의사항
[ 스프링 부트 설정 시의 주의사항 ]
스프링부트가 제공하는 테스트 어노테이션들은 모두 애플리케이션 컨텍스트를 만들어 조건에 맞는 빈들을 찾아서 등록한다. 그러다보니 애플리케이션 설정을 잘못하면 불필요하게 테스트 비용이 커지게 된다.
- 특정 기능을 위한 @Enable 어노테이션
- 빈 탐색을 위한 @ComponentScan
특정 기능을 위한 @Enable 어노테이션
스프링부트에서 테스트를 위한 애플리케이션 컨텍스트를 만들 때 설정의 기준이 되는 클래스는 @SpringBootApplication 어노테이션이 붙은 클래스이다. 일반적으로 해당 어노테이션은 메인 클래스에 존재하는데, 이러한 이유로 메인 클래스에는 특정한 기능을 위한 설정을 추가하지 않는 것이 좋다. 예를 들어 배치 설정 활성화를 위해 다음과 같이 등록했다고 하자.
@SpringBootApplication
@EnableBatchProcessing
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
문제는 @SpringBootApplication에 의해 해당 클래스가 테스트를 위한 기본 클래스가 되므로, @WebMvcTest나 @DataJpaTest 등 스프링부트가 제공하는 슬라이스 테스트를 사용할 때에도 Spring Batch에 대한 설정까지 활성화가 된다. 이것은 불필요하게 테스트를 무겁게 만들기 때문에 특정 기능을 위한 설정 클래스를 만들어 분리하는 것이 좋다.
@Configuration
@EnableBatchProcessing
public class MyBatchConfiguration {
}
빈 탐색을 위한 @ComponentScan
위와 마찬가지로 @ComponentScan을 설정해주는 것 역시 슬라이스 테스트를 진행할 때 부작용을 일으킬 수 있다. 예를 들어 우리가 다음과 같이 컴포넌트 스캔 설정을 해두었다고 하자.
@SpringBootApplication
@ComponentScan({ "com.mangkyu.app", "com.mangkyu.another" })
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
역시 스프링은 @SpringBootApplication을 참고해 애플리케이션 컨텍스트를 생성하는데, 오버라이딩한 컴포넌트 스캔에 의해 불필요한 빈들까지 등록이 된다. 예를 들어 위와 같이 설정에서 @DataJpaTest를 사용하면 컨트롤러부터 서비스 등 해당 위치의 모든 빈이 등록된다. 그러므로 이러한 이슈를 피하기 위해서는 역시 별도의 설정 클래스로 빼주는 것이 좋다. 만약 불가능하다면 테스트 패키지에 별도의 @SpringBootConfiguration을 만들거나 테스트에 대한 소스 위치를 지정하여 기본 설정을 비활성화할 수 있다.
2. 스프링 부트 테스트 작성 시의 주의사항
[ 스프링 부트 테스트 작성 시의 주의사항 ]
스프링부트가 제공하는 테스트 어노테이션들은 모두 애플리케이션 컨텍스트를 만들어 조건에 맞는 빈들을 찾아서 등록한다. 그러다보니 몇 가지 주의해야 할 부분들이 있는데, 이에 대해 살펴보도록 하자.
- 애플리케이션 컨텍스트 캐싱
애플리케이션 컨텍스트 캐싱
스프링 부트가 제공하는 테스트는 모두 애플리케이션 컨텍스트를 구성해주어야 한다. 하지만 모든 테스트마다 이를 구성하려면 비용이 커지므로 스프링은 테스트 시에 내부적으로 스프링 컨텍스트를 캐싱해두고 동일한 설정이라면 재사용한다. 그러므로 다음과 같이 애플리케이션 컨텍스트 설정에 변경을 주는 기능들은 테스트 시에 새로운 컨텍스트를 생성하도록 요구한다.
- @MockBean, @SpyBean
- @TestPropertySource
- @ConditionalOnX
- @WebMvcTest에 컨트롤러 지정
- @Import
- 기타 등등
@MockBean과 @SpyBean은 특정 빈을 Mock이 적용된 빈으로 등록한다. 그러므로 애플리케이션 컨텍스트가 갖는 빈이 달라져 새로운 컨텍스트를 생성하게 된다. 그러다보니 @MockBean과 @SpyBean을 많이 사용하면 테스트가 느려질 수 있으며 캐싱된 애플리케이션 컨텍스트의 수를 증가시킨다. 물론 테스트 클래스에서 @MockBean과 @SpyBean이 적용된 객체가 완전히 동일하다면 재사용한다.
그러므로 만약 현재 테스트 속도가 느리다면 테스트들마다 애플리케이션 컨텍스트가 생성되는지 확인해보도록 하자.
작업하면서 겪은 내용들을 위에 꾸준히 업데이트하여 공유하고자 합니다. 혹시 위에 적힌 내용들 외에도 추가적으로 알려주실 내용 있으면 댓글로 남겨주세요! 확인 후에 빠르게 해당 내용 반영하도록 하겠습니다:)
관련 포스팅
- 스프링부트 테스트를 위한 의존성과 어노테이션, 애플리케이션 컨택스트 캐싱(@SpringBootTest, @WebMvcTest, @DataJpaTest)
- 스프링 부트 설정/테스트 작성 시의 주의사항(스프링 부트 테스트가 오래 걸리는 이유)