JUnit 5 là thế hệ tiếp theo của JUnit. Mục tiêu: tạo nền tảng cập nhật cho developer-side testing trên JVM, tập trung Java 8+ và hỗ trợ nhiều phong cách test.
Có thể dùng cả Maven và Gradle.
Với Maven, thêm dependency vào pom.xml:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Các Annotation JUnit 5 phổ biến
Điểm thay đổi rõ rệt: test class và method không cần public nữa.
@Test
Đánh dấu method là test method. Không nhận attribute.
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class JUnit5Test {
@Test
void helloJUnit5() {
assertEquals(10, 5 + 5);
}
}
@ParameterizedTest
Chạy test nhiều lần với arguments khác nhau. Dùng @ParameterizedTest thay @Test. Phải khai báo ít nhất một source cung cấp arguments.
Ví dụ dùng @ValueSource cung cấp mảng String:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertTrue;
class JUnit5Test {
@ParameterizedTest
@ValueSource(strings = { "cali", "bali", "dani" })
void endsWithI(String str) {
assertTrue(str.endsWith("i"));
}
}
@RepeatedTest
Lặp lại test số lần chỉ định bằng @RepeatedTest. Mỗi lần chạy như một @Test bình thường. Hữu ích cho UI testing với Selenium.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
import org.junit.jupiter.api.TestInfo;
import static org.junit.jupiter.api.Assertions.assertEquals;
class JUnit5Test {
@RepeatedTest(value = 5, name = "{displayName} {currentRepetition}/{totalRepetitions}")
@DisplayName("RepeatingTest")
void customDisplayName(RepetitionInfo repInfo, TestInfo testInfo) {
int i = 3;
System.out.println(testInfo.getDisplayName() + "-->" + repInfo.getCurrentRepetition());
assertEquals(repInfo.getCurrentRepetition(), i);
}
}
Kết quả: test pass khi i==3, fail ở các lần khác.
@DisplayName
Đặt tên hiển thị tùy chỉnh cho test class/method.
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
@DisplayName("DisplayName Demo")
class JUnit5Test {
@Test
@DisplayName("Custom test name")
void testWithDisplayName() { }
@Test
@DisplayName("Print test name")
void printDisplayName(TestInfo testInfo) {
System.out.println(testInfo.getDisplayName());
}
}
@BeforeEach
Chạy trước mỗi test method (tương đương @Before JUnit 4).
import org.junit.jupiter.api.*;
class JUnit5Test {
@BeforeEach
void init(TestInfo testInfo) {
String callingTest = testInfo.getTestMethod().get().getName();
System.out.println(callingTest);
}
@Test void firstTest() { System.out.println(1); }
@Test void secondTest() { System.out.println(2); }
}
Kết quả: firstTest 1 secondTest 2
@AfterEach
Chạy sau mỗi test method (tương đương @After JUnit 4). Dùng để reset state.
import org.junit.jupiter.api.*;
class JUnit5Test {
@Test void firstTest() { System.out.println(1); }
@Test void secondTest() { System.out.println(2); }
@AfterEach void after(TestInfo testInfo) {
String callingTest = testInfo.getTestMethod().get().getName();
System.out.println(callingTest);
}
}
Kết quả: 1 firstTest 2 secondTest
@BeforeAll
Chạy một lần trước tất cả test (tương đương @BeforeClass). Phải static.
import org.junit.jupiter.api.*;
class JUnit5Test {
@BeforeAll static void init() { System.out.println("Only run once before all tests"); }
@Test void firstTest() { System.out.println(1); }
@Test void secondTest() { System.out.println(2); }
}
Kết quả: Only run once before all tests 1 2
@AfterAll
Chạy một lần sau tất cả test (tương đương @AfterClass). Phải static. Dùng để dọn dẹp.
import org.junit.jupiter.api.*;
class JUnit5Test {
@Test void firstTest() { System.out.println(1); }
@Test void secondTest() { System.out.println(2); }
@AfterAll static void after() { System.out.println("Only run once after all tests"); }
}
Kết quả: 1 2 Only run once after all tests
@Tag
Gán tag để lọc test ở class hoặc method level. Hữu ích tạo test pack.
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Tag("smoke")
class JUnit5Test {
@Test @Tag("login") void validLoginTest() { }
@Test @Tag("search") void searchTest() { }
}
@Disabled
Bỏ qua test ở class hoặc method level (tương đương @Ignore JUnit 4).
Class level:
@Disabled class DisabledClassDemo { @Test void testWillBeSkipped() { } }
Method level:
class DisabledTestsDemo {
@Disabled @Test void testWillBeSkipped() { }
@Test void testWillBeExecuted() { }
}