@SpringBootTest 는 어떻게 동작할까? (3)

정원식·2024년 12월 25일

Spring Test

목록 보기
3/4

개요

  • 본 시리즈에서는 @SpringBootTest 의 동작 원리를 확인합니다
  • 세번째 편에서는 테스트 환경 구성을 용이하게 해주는 어노테이션 및 유틸에 대해 살펴 봅니다.
    • Spring Test 와 Spring Boot Test 에서 제공해주는 기능을 각각 살펴 봅니다.

사용한 버전

  • junit-jupiter: 5.10.3
  • spring-boot-test: 3.3.4
  • spring-test: 6.1.13

Spring Test 스펙

@ContextConfiguration

  • Spring Test 스펙에서 컨텍스트 설정을 위해 사용하는 어노테이션입니다.
  • JUnit Jupiter 환경에서는 @SpringJUnitConfig 에 묶여서 사용됩니다.
  • 그러나.. Spring Boot 환경에서는 사용성이 낮습니다.
    실제 런타임과 유사한 환경의 통합 테스트가 필요할때는 @SpringBootTest 를 사용하면 되고
    유닛 테스트가 필요한 환경에서는 사용할 필요가 없으며..
    @SpringBootTest 보다는 빠르면서 유닛 테스트보다 컨텍스트 구성이 필요한 환경에서는 Sliced Test 를 사용하면 됩니다

알아두면 유용

  • @ActiveProfiles
    • 테스트 환경의 Profile 을 설정하기 위해 사용합니다.
  • @TestPropertySource
    • 테스트 환경에 프로퍼티 설정을 위해 사용합니다.
    • 여러 프로퍼티 중 사실상 가장 우선순위가 높습니다. 프로퍼티 우선순위
  • @DirtiesContext
    • ApplicationContext 의 상태가 변경되었음을 의미하여 테스트 종료후 컨텍스트가 종료됩니다. (AFTER_CLASS)
  • @RecordApplicationEvents
    • 해당 어노테이션 선언시, ApplicationEvents 를 통해 발생한 이벤트를 확인할수 있습니다.
    • ApplicationEventsTestExecutionListener 에 의해 테스트 메서드 실행 전후 ApplicationEvents 가 등록/해제 됩니다.
    • ApplicationEventsThreadLocal 에 저장되기에 비동기 로직의 경우, 정상적으로 이벤트 확인이 안될수 있습니다.

DB 관련

  • @Transactional
    • DB 관련 테스트 실행시, 테스트 종료 이후 롤백 처리가 필요한 경우 사용합니다.
    • 테스트 메서드 실행 전후, TransactionalTestExecutionListener 가 트랜잭션을 실행하고 종료 합니다.
    • 만약 테스트 이후 커밋 되어야 한다면 @Commit 을 사용합니다.
  • @Sql
    • 테스트 실행전, 특정 SQL 이 실행되어야 한다면 위 어노테이션을 사용할수 있습니다.
    • 보다 복잡한 구성이 필요하다면 아래 어노테이션도 참조해보세요.
      • @SqlConfig
      • @SqlMergeMode
      • @SqlGroup

그외

아주 아주 가끔 사용할 일이 있을것으로 보여 남겨놓습니다.

  • @TestExecutionListeners
    • 커스텀 TestExecutionListener 추가가 필요한 경우 사용
  • @ContextCustomizerFactories
    • 커스텀 ContextCustomizerFactory 추가가 필요한 경우 사용
    • ContextCustomizer 를 이용하여 ApplicationContext 를 수정할수 있습니다.
  • @ContextHierarchy
    • Context 간에 Parent-Child 구성이 필요한 경우

Utils

Spring Boot Test 스펙

@SpringBootTest

  • 현재 테스트 클래스를 중심으로 @SpringBootConfiguration 을 찾아 SpringApplication 을 실행합니다. (앞선 내용 참조)
    • @SpringBootConfiguration 이 없다면 @SpringBootTest(classes) 혹은 @ContextConfiguration 이 설정되어야 합니다.
  • 실제 애플리케이션이 실행되는 런타임과 유사하기에 대부분의 경우, 이슈 없이 통합 테스트를 수행할수 있습니다.

TestConfiguration

  • 테스트 환경에서만 사용하고 싶은 클래스가 있을때 사용합니다.
  • 테스트 클래스 내부에 정의하는 경우, 기존 설정들과 더불어 같이 사용됩니다. Detecting Test Configuration
    • @Configuration 을 테스트 클래스 내부에 정의하는 경우, 해당 설정이 기존 전체 설정을 덮어씁니다.
  • 독립된 클래스로 정의하는 경우, 해당 클래스는 따로 임포트되지 않고 명시적으로 @Import 해주어야만 사용이 가능합니다. Excluding Test Configuration
    • 특정 상황에서 공통적으로 사용되는 설정을 관리할때 편리합니다.

...Test (Sliced Test)

  • @SpringBootTest 가 너무 무거울때, 사용할수 있는 테스트 입니다. Auto-configured Tests, Slice Test 종류 및 임포트하는 AutoConfiguration

  • 전체 Configuration 을 로딩하는것이 아닌 일부(slice) 만 로딩하여 보다 빠릅니다.

  • 하지만 설정 지옥에 빠져 애플리케이션 로딩 자체가 어려운 경우들도 있습니다 ㅠ

  • 이를 헤어나오기 위한 팁으로는

    1. @SpringBootApplication절대 AutoConfiguration 관련 어노테이션을 붙이지 말것
      => Sliced Test 도 SpringApplication 을 기반으로 환경을 구성하여 어노테이션이 있는 경우, 해당 AutoConfiguration 을 임포트하게 됩니다.
      이로 인해 분명히 임포트 하지 않았는데, 실행시에는 디펜던시가 없다고 하는 상황이 발생합니다 ㅠㅜ
    2. @AutoConfigure... 를 적극 활용할것
      => 디펜던시가 없는 경우, 줄줄이 없는 경우가 대부분입니다. 이때 @AutoConfigure... 어노테이션을 활용하면 필요한 대부분의 AutoConfiguration 을 임포트 해줍니다.
    3. 마지막 한땀, 한땀 넣어주기
      => 특정 빈이 없다고 하는 경우, 결국 해당 빈이 정의된 AutoConfiguration 을 찾아 임포트 해주어야 합니다..
  • Slice Test 내에서 필요없는 빈이 등록되는 경우에는 Slice Test 내의 아래 필드를 활용할수 있습니다.

    • includeFilters
    • excludeFilters
    • excludeAutoConfiguration

결론

  • 세번째 편에서는 테스트 환경 구성을 용이하게 해주는 어노테이션 및 유틸에 대해 살펴 보았습니다.
  • 마지막 편에서는 직접 Sliced Test 를 작성해 봅니다.

Reference

Spring Test

Spring Boot Test

profile
매일매일 성장하고 싶은 백엔드 개발자입니다.

0개의 댓글