백엔드/스프링, 스프링부트, JPA, Spring Webflux

[Spring] JUnit 5 : 자바 테스팅 기반 프레임

Kangjieun11 2022. 9. 29. 20:09
728x90

JUnit ?

자바 개발자 93% 가 가장 많이 사용하는 단위 테스트 프레임워크
스프링 부트 2.2ver 이상부터 기본 제공

JUnit5 ?


JUnit5는 자바 개발자가 가장 많이 사용하는 테스팅 기반 프레임워크로, 자바 8 이상부터 사용가능하다.

JUnit5 = JUnit platform + JUnit Jupiter + JUnit Vintage

3가지가 결합한 형태



테스트 작성자를 위한 API, 모듈과 테스트 실행을 위한 API의 분리
ex ) JUnit Jupiter : 테스트 코드 작성에 필요한 junit-jupiter-api 모듈
테스트 실행을 위한 junit-jupiter-engine 모듈

JUnit5 구조


JUnit platform
테스트 실행 런처(Junit으로 작성한 테스트코드를 실행해주는 런처) 와 TestEngine API 제공
TestEngine을 통해 테스트 발견, 실행, 결과 보고

JUnit Jupiter
TestEngine API의 실제 구현체, JUnit5에서 제공,
jupiter-api를 사용해 작성한 테스트 코드를 발견하고 실행 함. (jupiter-api가 JUnit5에 새롭게 추가된 테스트 코드용 api임)

JUnit Vintage (하위버전과 호환을 위한 테스트 엔진 제공)
TestEngine API의 구현체, JUnit 3,4에서 제공
(기존 버젼으로 작성한 테스트 코드 실행할 때 Vintage-engine모듈 사용함.)

플랫폼을 통해 런처가 실행이되고, 5로 작성된건 쥬피터로, 3/4로 작성된건 빈티지로 테스트가 진행됨


JUnit 5 시작 (스프링 부트 프로젝트)
- 스프링 부트 2.2 이상부터는 기본적으로 의존성이 추가되는데, 아닌경우 의존성 추가 해주면됨 (우리는 스프링부트 2.2이상인가?)

// Spring boot 2.1 이하 version
// junit5 
testImplementation("org.springframework.boot:spring-boot-starter-test") {
 	exclude module : 'junit'
}

testImplementation("org.junit.jupiter:junit-jupiter-api")
testCompile("org.junit.jupiter:junit-jupiter-params")
testRuntime("org.junit.jupiter:junit-jupiter-engine")

test {
	useJUnitPlatform()
}




//Spring boot 2.2 이상 version
testImplementation("org.springframework.boot:spring-boot-starter-test")
 
test {
    useJUnitPlatform()
}

JUnit5의 Annotation

JUnit5
어노테이션
내용 JUnit4
어노테이션
@Test 테스트 Method임을 선언함. @Test
@ParameterizedTest 매개변수를 받는 테스트를 작성할 수 있음. (여러개의 다른 매개변수를 대입해가면 반복 실행 시 사용)  
@RepeatedTest 반복되는 테스트를 작성할 수 있음. (성능적인 이슈에 사용가능)  
@TestFactory @Test로 선언된 정적 테스트가 아닌 동적으로 테스트를 사용함.  
@TestInstance 테스트 클래스의 생명주기를 설정함.  
@TestTemplate 공급자에 의해 여러 번 호출될 수 있도록 설계된 테스트 케이스 템플릿임을 나타냄.  
@TestMethodOrder 테스트 메소드 실행 순서를 구성하는데 사용함.  
@DisplayName 테스트 클래스 또는 메소드의 사용자 정의 이름을 선언할 때 사용함. (어떤 테스트인지 표현가능, 공백/이모지/특수문자 모두 지원)  
@DisplayNameGeneration 이름 생성기를 선언함. 예를 들어 '_'를 공백 문자로 치환해주는 생성기가 있음. ex ) new_test -> new test  
@BeforeEach 모든 테스트 실행 전에 실행할 테스트에 사용함. @Before
@AfterEach 모든 테스트 실행 후에 실행한 테스트에 사용함. @After
@BeforeAll 현재 클래스를 실행하기 전 제일 먼저 실행할 테스트 작성하는데, static로 선언함. @BeforeClass
@AfterAll 현재 클래스 종료 후 해당 테스트를 실행하는데, static으로 선언함. @AfterClass
@Nested 클래스를 정적이 아닌 중첩 테스트 클래스임을 나타냄. (테스트 클래스 안에 내부 클래스 정의해 테스트 계층화할 때 사용)  
@Tag 클래스 또는 메소드 레벨에서 태그를 선언할 때 사용함. 이를 메이븐을 사용할 경우 설정에서 테스트를 태그를 인식해 포함하거나 제외시킬 수 있음.  
@Disabled 이 클래스나 테스트를 사용하지 않음을 표시함.(테스트를 하고 싶지 않을 떄) @Ignore
@Timeout 테스트 실행 시간을 선언 후 초과되면 실패하도록 설정함.  
@ExtendWith 확장을 선언적으로 등록할 때 사용함.  
@RegisterExtension 필드를 통해 프로그래밍 방식으로 확장을 등록할 때 사용함.  
@TempDir 필드 주입 또는 매개변수 주입을 통해 임시 디렉토리를 제공하는데 사용함.


Jupiter API : Assertions (주장, 행사, 단정문)

- org.junit.jupiter.api.Assertions
- 테스트 케이스의 수행 결과를 판별하는 메서드
- 모든 JUnit Jupiter Assertions는 Static 메서드이다.

<값 검증을 위한 assert로 시작하는 static한 메서드>

  • assertEquals(expected, actual) : int, long 등 기본타입과 Object에 대한 assertEquals 메서드가 존재한다.
  • assertNotEquals(Object unexpected, Object actual)
  • assertTrue(boolean condition)
  • assertFalse(boolean condition)
  • assertNull(Object actual)
  • assertNotNull(Object actual)
  • assertAll() : assert로 여러개 검증할 때 사용
    • 매개변수로 받은 모든 테스트코드를 한번에 실행
    • 오류가 나도 끝까지 실행 후 한번에 출력
  • assertThrows(ArithmeticException.class, () -> divide(100,0)) : 실행한 코드에서 특정 익셉션이 발생하는지 확인
    • 예외 발생을 확인하는 테스트
    • executable의 로직이 실행하는 도중 expectedType의 에러를 발생시키는 지 확인
    • assertDoesNotThrow()  : 예외가 던져지지 않음을 검증하는 단정문 (JUnit 5.2 부터 추가)
  • assertTimeout(duration, executable) : 
    • 특정 시간안에 실행이 완료되는지 확인
    • duration : 원하는 시간
    • executable : 테스트할 로직
  • fail()


Assumption <?>

CI 와 같이 특정 환경에 있을 떄만 테스트를 진행하도록 할 때 사용함.

<전제문이 true일 때 실행하고, false이면 종료>

assumeTrue: false일 때 이후 테스트 전체가 실행되지 않음
assumingThat : 파라미터로 전달된 코드블럭만 실행되지 않음


출처

https://insight-bgh.tistory.com/507
https://steady-coding.tistory.com/349
https://youtu.be/EwI3E9Natcw
https://lovon.tistory.com/108