Spring Context on Test
오늘은 Spring Context와 Junit의 Life Cycle에 대해 알아보는 시간을 가질까 합니다
이전 게시글에 작성된 Junit의 Life Cycle에 대해 보고 오셨나요..? ㅎㅎ
참고: huisam.tistory.com/entry/junit
일반적으로 Junit은 Method 혹은 Class 단위로 Life Cycle을 가집니다
하지만, @SpringBootTest 라고 일컫는 통합테스트는 Life Cycle이 조금 다른데요.
우리는 여러 테스트를 작성하고, 독립성과 병렬성을 보장받기 위해서는 이에 대한 이해가 필요합니다.
Spring Context?
그렇다면 Spring Context라는 것은 대체 무슨 말일까요?
자세한 내용은 전부 @ContextConfiguration 에 나타나 있습니다
어노테이션 첫줄에도 설명이 나와있듯이..
ApplicationContext에 대해서 IntegrationTest 를 하기 위한 Class Meta data 들을 담고 있고,
어떻게 Bean들을 Load 할 것인지 나타낸다
어떤 Bean 들을 로드할 것이고, 테스트에 활용할 것인지를 명시해주고, 이를 하나의 문맥(=Context)로 관리하겠다
라는 내용을 담고 있습니다
즉, Spring은 IntegrationTest 를 구동할 때, Bean들을 개별적으로 관리하는 것이 아니라
하나의 Context 단위로 관리한다는 의미입니다.
한번 예시로 들어가볼까요.?
Context | Bean |
1번 Context | A,B,C |
2번 Context | A,B |
3번 Context | A,B,C |
Context 에서 활용되는 Bean들을 예시로 들어본 것인데요.
총 Bean들을 3번 로드하는 경우가 있다고 가정해봅시다.
위의 표대로 Bean들을 로드한다고 하면, 1번을 로드하고, 3번을 로드할 때는
새롭게 로드하는 것이 아니라 다시 1번 Context를 재활용하게 됩니다
대신 2번은 새롭게 로드하게 됩니다. 이전의 Context와는 서로 다른쌍이기 때문이죠
직접 디버그하고, 눈으로 볼 수 있는 Tool 이 있다면, 참 좋을텐데요.
아쉽게도 필자는 그러한 방법을 알지 못하여 ㅠㅠ 알려주시면 댓글로 남겨주세요.
Context Caching
스프링에서는 위와 같은 Context를 어떻게 캐싱한다는 말일까요.?
Once the TestContext framework loads an
ApplicationContext(or WebApplicationContext) for a test,
that context is cached and reused for all subsequent tests that declare the same unique context configuration within the same test suite.
To understand how caching works, it is important to understand what is meant by “unique” and “test suite.”
번역하면,,
TestContext 프레임 워크 가 테스트에 대해
ApplicationContext(또는 WebApplicationContext)을 로드하면
해당 컨텍스트가 캐시되고 동일한 테스트 스위트 내에서 동일한 고유 컨텍스트 구성을 선언하는 모든 후속 테스트에 재사용됩니다.
캐싱이 작동하는 방식을 이해하려면 "고유"및 "테스트 스위트"가 의미하는 바를 이해하는 것이 중요합니다.
한마디로, 캐싱 전략이 따로 존재한다는 의미인데요.
여러 요인들에 의해 캐싱키를 결정하게 됩니다.
여기서 가장 중요한 요인들은
- ActiveProfiles: 어떤 Profile을 사용하는지
- MockBean, SpyBean: Bean을 Mocking 할 것인지
- Classes: 어떤 Class를 로드할 것인지
- Property: 어떤 Property를 사용할 것인지
위와 같은데요.
그래서 전략적으로 테스트를 작성하는 것이 중요합니다.
최대한, 많은 Bean들과 공통된 속성들을 유지하면 할 수록, Context를 로딩하는 횟수는 줄어들겠죠.?
Context를 로딩하는 횟수가 줄어들수록, 메모리도 덜 차지하게 되고, 테스트를 구동하는 시간도 줄어들게 됩니다 ㅎㅎ
한마디로, 우리의 테스트 시간을 줄여주고, 메모리도 덜 뺏는다 이것입니다
빠른 개발과 빠른 피드백을 위해서는 너무나 중요하겠죠.?
총 테스트 시간이 10분이 걸리는 것과, 1분이 걸리는 것은 개발 생산성이나 속도 측면에서 압도적일 수 밖에요.. :)
또한 스프링에서는 캐싱해주는 최대 메모리도 존재하는데요 ㅎㅎ
spring.test.context.cache.maxSize=32
default 값으로는, context cache size를 32MB 로 유지하고 있습니다
결론
결론적으로 말씀드리면 위와 같은 형태로 요약되는 형태입니다.
- Junit은 일반적으로 Class (혹은 Method) 의 Life Cycle을 가진다
- Spring Context는 Module 단위의 테스트가 끝날때까지 Caching 전략을 따른다
- Caching 전략은 어떻게 테스트를 작성하느냐에 따라 달렸다
Spring Boot Integration Test
'Developer > Spring' 카테고리의 다른 글
[JPA] DataSource 를 연결하는 방법 & RoutingDataSource 설정 (2) | 2021.06.19 |
---|---|
Spring Batch란? - 기본 요소에 대해 알아보자 (0) | 2021.06.12 |
번외편 - Junit LifeCycle과 @ExtendWith 에 대해 알아보자 (0) | 2021.05.02 |
Spring Cloud Feign Testing - Feign Client를 테스트해보자 (6) | 2021.04.11 |
Spring Data JPA - 영속성 상태에 대해서 (2) | 2021.03.02 |