모르지 않다는 것은 아는것과 다르다.

Junit

단위테스트 vs 통합테스트

채마스 2022. 2. 27. 01:46

테스트

  • 코드의 안정성을 높이고, 기능을 추가하거나 수정하면서 발생하는 부작용(Side-Effect)를 줄일 수 있다.
  • 기존 코드를 수정하는 것에 대한 불안감을 줄일 수 있고, 결과적으로 생산성을 높여줄 수 있다.
  • 테스트는 외부의 문제가 발생하지 않는이상 계속해서 일관적인 결과를 제공해주어야 한다.
  • 스프링부트 테스트는 크게 단위테스트와 통합테스트로 나뉜다.
  • 스프링부트 테스트 관련 애노테이션은 아래와 같습니다.

 

단위테스트란

  • 단위 테스트는 가장 작은 단위의 테스트다.
  • 슬라이스 테스트 라고도 한다.
  • 개발 단계에서 각 모듈이 개발완료된 시점에서 수행되는 테스트다.
  • F.I.R.S.T 단위 테스트 원칙
    • Fast : 테스트 코드를 실행하는 일은 오래 걸리면 안된다.
    • Independent:독립적으로 실행이 되어야 한다.
    • Repeatable : 테스트는 실행할 때마다 같은 결과를 만들어야 한다.
    • Self-validating : 메뉴얼 없이 테스트 코드만 실행해도 성공, 실패 여부를 알 수 있어야 한다.
    • Timely : 유닛 테스트는 프로덕션 코드가 테스트를 성공하기 직전에 구성되어야 한다. 즉, 바로 사용가능해야 한다.
  • @ExtendWith(MockitoExtension.class)를 통해 테스트 진행한다.
  • 모듈이 개발 완료되는 시점에서 개발자가 명세서 기반으로 정확히 개발했는지 테스트 진행한다.
  • 새로운 기능 추가 시 수시로 빠르게 테스팅 가능하다.
  • 개발한 것에 대해 빠르게 검증 받는 것이 단위테스트의 장점이다.
  • TDD(Test-Driven Development, 테스트 주도 개발)에서 얘기하는 테스트는 단위테스트를 의미다.
  • 대부분의 테스트코드는 유닛 테스트코드로 작성하는것을 원칙으로 하고, 컴포넌트간의 전체 프로세스를 테스트할 때만 통합테스트를 작성한다.
  • 단위 테스트의 문제점
    • 단위 테스트는 해당 모듈에 대한 독립적인 테스트이기 때문에 다른 객체와 메세지를 주고 받는 경우에 문제가 발생한다.
    • 다른 객체 대신에 가짜 객체(Mock Object)를 주입하여 어떤 결과를 반환하라고 정해진 답변을 준비시켜야 하는데, 이를 stub이라고 한다.
  • 대표적인 슬라이스 테스트 애노테이션 종류로는 아래와 같다.
    • @DataCassandraTest
    • @DataJdbcTest
    • @DataJpaTest
    • @DataLdapTest
    • @DataMongoTest
    • @DataNeo4jTest
    • @DataR2dbcTest
    • @DataRedisTest
    • @JdbcTest
    • @JooqTest
    • @JsonTest
    • @RestClientTest
    • @WebFluxTest
    • @WebMvcTest
    • @WebServiceClientTest

 

통합테스트

  • 모듈을 통합하는 과정에서 모듈 간 호환성의 문제를 찾아내기 위해 수행되는 테스트다.
  • @SpringBootTest를 통해 테스트 진행한다.
  • 모듈 간의 연결 작업이 올바르게 연계되어 작동하는지를 테스트하는 과정이다.
  • 여러 모듈간 통합을 거치기 때문에 단위 테스트에 비해 테스트 실행 속도가 느린 편이다.

 

@SpringBootTest

  • 통합 테스트를 위해 제공하는 기본적인 스프릉부트 테스트 어노테이션이다.
  • 기능검증이 아닌,실제 플로우의 동작을 검증하기 위해 사용한다.
  • @SpringBootTest 에는 아래와 같은 메타 애노테이션이 포함되어 있다.
  • 실제 구동되는 애플리케이션과 똑같이 컨텍스트를 로드하여 모든 Bean을 등록하고 테스트를 하기 때문에 애플리케이션의 규모가 클수록 느려진다.
  • @SpringBootApplication을 찾아서 테스트를 위한 빈들을 다 생성한다. 그리고 @MockBean으로 정의된 빈을 찾아서 교체한다.

  • @SpringBootTest 어노테이션의 파라미터
    • value
      • 테스트가 실행되기 전에 적용할 프로퍼티를 주입 시킬 수 있다. 즉, 기존의 프로퍼티를 오버라이드한다.
    • properties
      • 테스트가 실행되기 전에 {key: value} 형식으로 프로퍼티를 추가 할 수 있음.
      • @SpringBootTest(properties = "classpath:application-test.yml")
      • 코드 예시
@SpringBootTest( properties = { "testId=born", "testName=탄생" } )
class TestApplication {
    @Value("${testId}")
    private String testId; 

    @Value("${testName}")
    private String testName;
}
  • args
    • application의 agruments를 삽입한다.
    • 코드 예시
@SpringBootTest( args = {"--app.test=one", "--app.test2=two"} )
class TestApplication {
    @Value("${app.test}")
    private String appTest;

    @Autowired
    private ApplicationArguments args;

    @BeforeEach
    public void setUp() {
        assertThat(args.getOptionNames()).containsOnly("app.test");
        assertThat(args.getOptionValues("app.test")).containsOnly("one");
    }
}
  • classes
    • 애플리케이션 컨텍스트에 로드할 클래스를 지정 할 수 있다.
    • 따로 지정하지 않으면 @SpringBootConfiguration을 찾아서 로드한다. -> 애플리케이션 상에 정의된 모든 빈을 생성한다.
    • ex> @SpringBootTest(classes = {ArticleServiceImpl.class, CommonConfig.class})
    • 코드 예시
@SpringBootTest(classes = {ArticleServiceImpl.class, CommonConfig.class})
class TestApplication {
    @Autowired
    private ArticleServiceImpl articleServiceImpl;

    @Autowired
    private RestTemplate restTemplate;
}
  • webEnvironment
    • 애플리케이션이 실행될 때의 웹 환경을 설정할 수 있음. 기본 값은 Mock 서블릿을 로드하여 구동되며 예제에서는 랜덤 포트값을 주어 구동 시킨다.
    • ex> @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) -> 내장 톰켓 구동 안함
    • WebEnvironment.MOCK: mock servlet, embedded server 동작 x
      • @AutoConfigureMockMvc, @AutoConfigureWebTestClient 와 함께 써서 mock test 가능
    • RANDOM_PORT, DEFINED_PORT -> 내장 톰캣 사용 함
    • WebEnvironment.NONE: 웹 환경 구성 안 함, embedded server 동작 x

 

정리

  • @SpringBootTest 및 test Slices를 아래와 같이 정리할 수 있다.

 

 

REFERENCES

'Junit' 카테고리의 다른 글

테스트 더블  (0) 2022.02.27
WebMvc Test  (0) 2022.02.27
Service 단위테스트  (0) 2022.02.27
Repository 단위테스트  (0) 2022.02.27
MockMvc  (0) 2022.02.27