DevBoi

[Springboot]Springboot_test 본문

Develop/[Test Code]

[Springboot]Springboot_test

HiSmith 2022. 4. 26. 14:51
반응형

1. TDD (테스트 주도 개발 방법 , 테스트 코드 작성의 목적)

-코드의 안정성을 높일수 있다.

-기능을 추가하거나, 변경하는. 과정에서 발생할 수 있는 side-effect를 줄일 수 있다.

-해당 코드가 작성된 목적을 명확하게 표현할 수 있다.

 

 

2. Junit 이란?
독립된 단위테스트를 지원해주는 프레임워크
단정 메서드로 테스트 케이스의 수행 결과를 판별한다.

 


3. Junit 4 , Junit5 두개 차이는?

3-1) 자동지원 스펙 차이
spring 2.2 버전 부터는 자동 Junit5, 그 전은 Junit4

 

3-2) 구성 차이
Junit5는, JUnit Platform +. Junit Jupiter + Junit Vintage 
-platform : 테스트 개발을 위한 API 제공, 테스트를 발견하고, 테스트 계획을 생성하는 인터페이스를 가지고있다.(IDE를 연동하거나 콘솔 출력등을 지원한다.)
-Jupiter :  Test Engine, jupiter-api를 사용하여, 작성한 테스트 코드를 발견하고 실행하는 역할을 수행
-Vintage : 하위 호환성을 위함,Junit3,4의 실행을 위해 존재한다.

 

3-3) 문법

@SpringbootTest (ExtendWIth)

-> 거의 통합 테스트 용도, SpringBootApplication을 찾아가 하위의 모든 Bean을 찾아가 스캔하고 로드한다.

그 후  Application Context를 로드하여, Bean을 추가하고, MockBean을 찾아 교체한다.

SpringBootTest는 실제 스프링을 실행하고, 포트주소가 Listening되어져 DB커넥션이 붙어지는 상태에서 진행되는 Live 테스트 방법

(클래스 이름을 따로 명시하여 특정 클래스에대한 컴포넌트만 로드할 수도 있긴하다.)

스프링이 실행되기때문에 스프링이 제공하는 DI등을 사용할 수 있다.

 

 

@WebMvcTest

MVC를 위한 테스트이다. 대표적으로 웹에서 테스트하기 어려운 Controller테스트들이 있다.

Request,Response에 대해서 테스트 할 수있는 어노테이션이다.

@Controller,ControllerAdvice,JsonComponent와 FIlter,WebConfigurer등만 로드되기 때문에, SpringbootTest보다 가볍게 테스트할 수 있다는 장점이 있다.

또한 Controller에서 사용하는 다른 레이어는 MockBean으로 생성하여, 의존성을 주입할 수 있다.

예시 코드 )

 

@ExtendWith

Junit4 의 Runwith 가 변경된 것이다.

ExtendWith는 메인으로 실행될 Class를 지정할 수 있다.

@SpringBootTest는 기본적으로 ExtendWIth가 들어가있다.

 

@WebMvcTest(~~.class)

괄호안에 클래스만 로드하여 테스트 진행

매개변수를 지정해주지 않으면, @Controller,@RestController,@RestControllerAdvice등 모두 로드된다.

컨트롤러와 연관된 빈이 모두 로드된다

스프링의 모든 Bean을 로드하는 @SpringBootTest대신 컨트롤러 관련 코드만 테스트 할 경우 사용한다.

 

@MockBean

Controller의 API를 테스트하는 용도인 MockMvc객체를 주입받는다.

perform메소드를 활용하여, 컨트롤러의 동작을 확인할 수 있다.

.andExcept(), andDO, andReturn등의 메소드를 같이 활용한다.

테스트할 클래스에서 주입받고있는 객체에 대해 가짜 객체를 생성해주는 어노테이션

해당 객체는 실제 행위를 하지 않는다.

given() 메소드를 활용하여, 가짜 객체의 동작에 대해 정의하여 사용할 수 있다.

 

@AutoConfigureMockMvc

spring.test.mockmvc의 설정을 로드하면서 MockMvc의 의존성을 자동으로 주입한다.

MockMvc클래스는 Rest api테스트를 할 수 있는 클래스

(Mock으로 Rest api 테스트를 할 수 있다.)

 

 

 

 

4. 통합 테스트란?

전체 비즈니스 로직이 제대로 동작하는지 확인하는 것을 의미한다.

한번씩 실행할때마다 모든 빈을 로드하기 때문에, 반복성의 속도가 떨어진다.

 

- 장점 ) 애플리케이션의 설정, 모든 Bean을 모두 로드하기 때문에 운영환경과 가장 유사한 테스트가 가능, 전체적인 Flow를 쉽게 테스트 가능하다
- 단점 ) 애플리케이션의 설정, 모든 Bean을 모두 로드하기 떄문에 시간이 오래 걸리고 무겁다.
테스트 단위가 크기 떄문에 디버깅이 어렵다

 

물론, SpringbootTest클래스를 지정해서 로드되는 빈을 제한 할 수 있지만,

스프링이 실행된다는 관점에서, 단위테스트보다 통합 테스트라고 보는것이 맞다.

또한 Springboottest어노테이션은 기본적으로 서블릿 서버를 실행하지 않지만, WebEnvironment속성을 사용하면

컨테이너가 서블릿환경에서 작동되도록 할 수 있다. 기본설정은 None이다.(Defined,Mock도있음)

 

 

5.단위 테스트란?

프로젝트에 필요한 모든 기능에 대한 테스트를 각각 진행하는 것을 의미한다.

Mock 객체와, given, willretun등을 사용하여, 가짜 객체에 대한 기댓값을 개발자가 정의할 수 있고, 

해당 기준으로 테스트가 가능하다.(Mock 객체를 사용하지 않는 단위테스트도 있다.)

 

* FIRST 원칙

-Fast : 테스트 코드의 실행은 빠르게 진행이 되어야 한다.

-Independent : 독립적인 테스트가 가능해야한다.

-REpeatable : 테스트는 매번 같은 결과를 만들어야 한다.

-Self-Vailidating : 테스트는 그 자체로 실행하여, 결과를 확인 할 수 있어야 한다.

-TImely : 단위 테스트는 비즈니스 코드가 완성되기 전에 구성하고 테스트가 가능해야한다

(다른 연결 모듈에 대한 완성전에도 테스트가 가능해야한다.)

 

가장 큰 단위 테스트의 핵심은, 스프링을 실행하지 않고, 테스트를 할수 있다는 것이다.

Mockito를 사용하여, mock을 만들면, 실제 연동로직이나, 실제 로직이 돌지않고

MockMethodInterceptor에서 인터셉트해서, 해당 mock으로 선언된 값으로 인터셉트된다.

하여, 직접 해당 로직이 동작하지 않아도 유닛테스트에서는 해당 값의 return값을 임의로 설정해서 테스트 할 수 있다.

 

단위테스트는, 실제 운영에서 스프링 프레임워크에 의존을 많이하고있기 때문에, 단위 테스트만으로

어플리케이션의 신뢰를 얻는다고 하기는 좀 힘들고, 전체에 대한 단위테스트 구현의 의미가 그렇게 높지도 않다.

비즈니스 핵심로직은 서비스단에 주로 작성을 한다. 해당 서비스에 대한 단위테스트는 의미가 크다.

왜냐면, 해당 서비스에 대한 코드는 어디서든 공통적으로 불러올수있고, 사용할 수있기때문에

해당 서비스 레이어에 대한 단위테스트는 의미가 많다고 개인적으로 생각한다. (추가로 디비 연동은 rdbms,nosql등등으로 변경될 소지도있다.)

6) 생명 주기

BeforeAll,BeforeEach,AfterAll,After Each, Test,RepeatedTest,ParameterizedTest, Disabled(원래 Ignore)
라이프 사이클 :  BeforeAll -> BeforeEach -> Test -> AfterEach -> AfterAll

beforeall, afterall에는 static 으로 메소드를 선언해야한다.


7) DisplayName


메소드명과 테스트 케이스 IDE에 출력되는 이름을 다르게 할 수 있다.

 




8) TestRestTemplate


spirng 4버전 이후 부터 지원하는 Spring http 통신 템플릿


MockMvc와 차이가 없는듯 보인다.

두개의 차이는 Servlet 컨테이너의 사용유무이다.

MockMvc는 서버 입장에서 구현한 API를 통해 비즈니스 로직이 문제없이 수행되는지 테스트 가능하다.

TestRestTemplate은 클라이언트 입장에서 RestTemplate을 사용하듯이 테스트를 수행할 수 있다.

(TestRestTemplate,SpringBootTest 는 서블릿컨테이너를 사용한다.)

 

@DataJpaTest

-@Transactional 포함되어있는 어노테이션

JPA관련 테스트 설정만을 로드하는데, DataSource의 설정이 유효한지, 정상인지

JPA를 이용해 DDL,DML이 정상적으로 작동하는지 확인

TestEntityManager를 사용하여, Jpa가 정상작동하는지 확인한다.

 

 

@MybatisTest

 

 

 

 

 

 

 

반응형

'Develop > [Test Code]' 카테고리의 다른 글

[Test Code] Spock Framework + TestContainers  (0) 2023.04.24
[Junit] Test coverage 확인하기_Jacoco  (0) 2022.04.27