BackEnd/Spring

[Spring] Test - @SpringBootTest

JJangGu 2022. 3. 20. 15:25

스프링부트에서 테스트를 하기 위한 도구들에 대해 학습해보고자 합니다.

그 중 첫번째로 @SpringBootTest 에 대해서 알아봅시다.

 

1. @SpringBootTest

@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Inherited
@BootstrapWith(value=SpringBootTestContextBootstrapper.class)
@ExtendWith(value=org.springframework.test.context.junit.jupiter.SpringExtension.class)
public @interface SpringBootTest

Spring Boot 기반 테스트를 실행하는 테스트 클래스에 지정할 수 있는 어노테이션입니다. 일반 Spring TestContext Framework 이상으로 다음 기능을 제공합니다.

  • 특정 @ContextConfiguration(loader=...) 이 정의 되지 않은 경우, SpringBootContextLoader 를 기본 ContextLoader 로 사용.
  • 중첩된 @Configuration 이 사용되지 않고 명시적 클래스가 지정되지 않은 경우, @SpringBootConfiguration 을 자동으로 검색합니다.
  • properties 속성을 사용하여 사용자 정의 환경 속성을 정의할 수 있습니다.
  • args 속성을 사용하여 애플리케이션 인수를 정의할 수 있습니다.
  • DEFINED, RANDOM 포트에서 수신 대기하는 실행중인 웹서버를 시작하는 기능과, 다양한 webEnvironment 모드에 대한 지원을 제공합니다.
  • 완전히 실행되는 웹 서버를 사용하는 웹 테스트에서 사용할 TestRestTemplate 또는 WebTestClient 빈을 등록합니다.
 

SpringBootConfiguration (Spring Boot 2.6.4 API)

Specify whether @Bean methods should get proxied in order to enforce bean lifecycle behavior, e.g. to return shared singleton bean instances even in case of direct @Bean method calls in user code. This feature requires method interception, implemented thro

docs.spring.io

@SpringBootTest 에 대한 정의와 기능은 이렇게 정의되고 있습니다.

 

그러면 우리는 언제 이 유용한 기능들을 활용해야 될지 생각을 해봐야합니다.

 

2. 단위 테스트 vs 통합 테스트 vs 인수 테스트

- 단위 테스트

응용 프로그램에서 테스트 가능한 작은 소프트웨어를 실행하여 예상대로 동작하는지 확인하는 테스트.

 

단위 테스트는 보통 메서드, 클래스 단위로 정해지는데, 단위의 크기가 작을수록 복잡성이 낮아진다.

TDD 를 할때 강력하게 장점이 드러나는데, TDD가 성공하기 위한 여러개의 조건들 중 하나가 작은 단위의 테스트 작성이라고 생각한다.

작은 단위의 테스트를 만들어야 복잡한 메서드가 만들어지지 않으며, OOP를 설계하기 유리해진다.

 

- 통합 테스트

단위 테스트보다 더 큰 동작을 달성하기 위해 여러 모듈들을 모아 이들이 의도대로 협락하는지 확인하는 테스트.

 

통합 테스트는 개발자가 변경할 수 없는 외부라이브러리나 DB등 모든 요소와 환경들이 제대로 작동하는지 확인하는 용도로도 사용한다.

단위 테스트로 테스트한 작은 단위의 기능들이 모여 통합테스트를 이루는것도 어느정도 맞지만, 단위 테스트가 다 성공한다고 통합테스트가 무조건 성공하지 않는다. 즉 단위테스트에서는 발견하기 힘든 환경적 요인들로 인한 버그를 잡아낼 수 있다.

 

- 인수 테스트

사용자(고객)의 시나리오에 맞추어 수행하는 테스트.

 

인수 테스트는 고객의 니즈에 초점이 맞추어져 있다. 고객의 시나리오에 중점을 두고 프로젝트에 참여하는 사람들이 이를 토대로 프로젝트를 진행한다. 이렇게 되면 의사소통과정에서 다른길로 빠지지 않고, 공통된 목표로 나아간다는 점에서 장점이 있다.

또한 고객의 요구사항을 계속 점검할 수 있다.

개발자의 측면에서는 고객의 시나리오를 작성하고, 그거에 따른 given, when, then 패턴을 생각하며 테스트를 작성할 수 있고

이와 TDD를 융합한다면, 고객의 요구를 놓지지 않으며 효과적으로 클린한 코드를 만들 수 있다.

 

3. @SpringBootTest 는 언제?

결국 이것을 언제 써야되는지를 얘기하기 위해서 앞에서 단위 테스트, 통합 테스트, 인수 테스트에 대한 얘기를 했습니다.

보통 @SpringBootTest 는 통합테스트 시 사용을 합니다.

 

왜 그럴까 생강을 해보면, @SpringBootTest 를 사용하면 Spring 의 어플리케이션 컨텍스트에서 Bean을 모두 스캔하고, 

mock bean 이 있다면 그것으로 교체한다. 즉, Spring에 구성한 환경을 구축합니다.

그렇기에 통합테스트에 더 맞는 어노테이션입니다.

 

하지만 고민해야할 지점은, 같은 통합테스트라고 할지라도 태스트의 목적에 따라 안에 사용할 기술들이 달라질 수 있다는 점입니다.

@SpringBootTest를 붙이고 통합테스트를 할 때, MockMvc 를 사용하여 스터빙을 하고 가짜 객체들을 주입할 지, 

RestAssured 를 활용하여 end-to-end 테스트를 진행할지에 대한 고민을 해야합니다.

 

@WebMvcTest, @mockBean 와 같은 다른 테스트도구들은 다음 글에서 알아보겠습니다.