코코코딩공부

테스트를 더 빠르게 진행시켜보자

Ocean_ 2023. 10. 21. 18:16

ApplicationContext 개선

우리의 서비스는 TestContainer 를 사용중인데 이로 인해 테스트 실행시 컨테이너가 실행되며 처리되는 시간이 길어졌다. 이런 테스트 속도를 개선하고자 하였다.

 

Application Context

Spring TestContext Framework는 ApplicationContext 인스턴스와 WebApplicationContext 인스턴스를 로딩하고 캐싱하는 기능을 한다.

이를 통해 한 번 로드된 컨텍스트를 캐시에 저장해두고 동일 환경 시 해당 컨텍스트를 재사용한다. 만약 이전 테스트와 다른 환경의 컨텍스트가 필요하다면 컨텍스트가 로딩된다.

현재 우리 서비스는 총 11개의 Context 생성된다.

테스트를 진행하면서 다른 환경의 컨텍스트가 빈번하게 발생할 경우 처리되는 시간이 매우 느려질 가능성이 있다. 이를 최적화 해보기로 하였다.

 

이유

https://docs.spring.io/spring-framework/reference/testing/testcontext-framework/ctx-management/caching.html

다음과 같은 공식문서에서는

contextCustomizers(from ContextCustomizerFactory) – this includes @DynamicPropertySource methods as well as various features from Spring Boot’s testing support such as @MockBean and @SpyBean.

@MockBean and @SpyBean이 객체마다 다르게 선언되어 있으면 Context를 재사용할 수 없고 새롭게 생성된다고 한다.

우리의 서비스도 @MockBean 과 @SpyBean이 객체마다 다르게 사용되고 있었다. 이를 줄일 필요가 있었다.

 

개선

class LikedCafeControllerTest extends BaseControllerTest {

    @Autowired
    private MemberRepository memberRepository;
    @Autowired
    private CafeRepository cafeRepository;
    ~~@MockBean~~
    ~~private JwtTokenProvider jwtTokenProvider;~~
    ...
}

다음과 같이 실제객체를 사용할 수 없어 MockBean으로 구성되어있는 객체를 BaseControllerTest 에서 한번에 상속받아 사용하게 한다.

 

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ExtendWith(RestDocumentationExtension.class)
public abstract class BaseControllerTest extends BaseTest {

    @LocalServerPort
    private int port;

    @SpyBean
    protected S3Client s3Client;
    @SpyBean
    protected JwtTokenProvider jwtTokenProvider;
}

기존에 실제 객체를 사용한 클래스들도 존재하기 때문에 이를 @MockBean에서 @SpyBean 으로 변경하였고 처리하였다.

이로 인해 Application Context가 새로 생성되는 횟수가 11회에서 4회로 줄었고 테스트 속도도 18%정도 단축되었다.