Junit이란?
Junit이란?
JUnit이란 Java 언어에서 가장 널리 사용되는 단위 테스트 프레임워크 중 하나이다. JUnit을 사용하면 코드의 특정 부분(주로 메서드)을 독립적으로 테스트할 수 있으며, 어노테이션 기반으로 동작한다.
Spring Boot 2.2버전 이전에는 Junit4를 많이 사용하고 있으며, Spring Boot 2.2부터는 Junit5를 사용하고 있다.
Junit5는 JUnit Platform과 JUnit Jupiter, Junit Vintage으로 이루어져 있다.
JUnit Platform: 테스트를 실행해주는 런처와 TestEngine API를 제공
Jupiter: TestEngine API 구현체로 JUnit5에서 제공
Vintage: TestEngine API 구현체로 JUnit3, 4에서 제공
Junit5의 라이프 사이클
@BeforeAll
모든 테스트 메소드가 실행되기 전에 한 번만 실행된다.
- 테스트 클래스 전반에서 사용할 리소스를 초기화하는 데 사용된다. 예를 들어, 데이터베이스 연결을 설정하거나 외부 API 호출에 필요한 초기 설정을 수행할 수 있다. 메서드는 반드시 static이어야 한다.
@BeforeEach
각 테스트 메소드가 실행되기 전에 실행된다.
- 각 테스트가 실행되기 전에 객체 초기화 또는 설정을 수행할 수 있다. 각 테스트는 독립적이므로 테스트 환경을 일관성 있게 재설정하는 데 사용된다.
@Test
실제로 테스트가 실행되는 메소드를 나타낸다.
- 테스트하고자 하는 로직을 실행하고, 기대 결과와 실제 결과를 비교하며, assertEquals, assertTrue 등의 검증 메서드를 사용하여 테스트 결과를 검증한다.
@AfterEach
각 테스트 메소드가 실행된 후에 호출된다.
- 테스트가 끝난 후 테스트 환경을 정리하는 데 사용된다. 예를 들어, 열린 리소스를 닫거나 메모리 정리를 할 수 있다.
@AfterAll
모든 테스트가 완료된 후 한 번만 실행된다.
- 테스트 클래스에서 사용한 전역 자원을 해제하거나 정리하는 데 사용된다. 예를 들어, 데이터베이스 연결을 종료하거나 외부 리소스를 정리할 수 있다. 메소드는 반드시 static이어야 한다.
JUnit5의 주요 어노테이션
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 | 필드 주입 또는 매개변수 주입을 통해 임시 디렉토리를 제공하는데 사용함. |
라이프 사이클 테스트
아래 코드를 실행하면
beforeAll() → beforeEach() → test1() ->afterEach() → beforeEach() → test2() → afterEach()→ @AfterAll 과 같은 순으로 메소드가 실행 되어야 한다.
@BeforeAll
static void beforeAll() {
System.out.println("## BeforeAll Annotation 호출 ##");
System.out.println();
}
@AfterAll
static void afterAll() {
System.out.println("## afterAll Annotation 호출 ##");
System.out.println();
}
@BeforeEach
void beforeEach() {
System.out.println("## beforeEach Annotation 호출 ##");
System.out.println();
}
@AfterEach
void afterEach() {
System.out.println("## afterEach Annotation 호출 ##");
System.out.println();
}
@Test
void test1() {
System.out.println("## test1 시작 ##");
System.out.println();
}
@Test
@DisplayName("Test Case 2!!!")
void test2() {
System.out.println("## test2 시작 ##");
System.out.println();
}
@Test
@Disabled
// Disabled Annotation : 테스트를 실행하지 않게 설정하는 어노테이션
void test3() {
System.out.println("## test3 시작 ##");
System.out.println();
}
테스트를 실행하면 아래 사진과 같이 잘 실행 되었고, test3()는 @Disabled 어노테이션에 의해 호출되지 않음을 알 수 있다. 또한, test2()는 @DisplayName을 주었기 때문에 TestLifeCycle에 입력한 "Test Case 2!!!"로 정상 출력됨을 알 수 있다.
참고
테스트 코드 적용하기 (JUnit, TDD) [ 스프링 부트 (Spring Boot) ] (youtube.com)