JUnit 5 注解:每个注解背后的含义
JUnit 5 的注解体系比 JUnit 4 更清晰。理解每个注解的作用时机,比背下来更重要。
测试生命周期注解
这些注解定义了测试的执行顺序:
java
import org.junit.jupiter.api.*;
class LifecycleDemo {
@BeforeAll // 1. 全测试类只执行一次,必须 static
static void beforeAll() {
System.out.println("在所有测试之前执行一次");
}
@AfterAll // 2. 全测试类只执行一次,必须 static
static void afterAll() {
System.out.println("在所有测试之后执行一次");
}
@BeforeEach // 3. 每个测试方法执行前都执行
void beforeEach() {
System.out.println("每个测试之前");
}
@AfterEach // 4. 每个测试方法执行后都执行
void afterEach() {
System.out.println("每个测试之后");
}
@Test
void test1() {
System.out.println("Test 1");
}
@Test
void test2() {
System.out.println("Test 2");
}
}执行顺序:beforeAll → beforeEach → test1 → afterEach → beforeEach → test2 → afterEach → afterAll
@DisplayName:自定义测试名
让测试报告更可读:
java
@Test
@DisplayName("用户注册 - 正常流程")
void userRegistration() { }
// 支持中文、emoji、特殊字符
@Test
@DisplayName("✅ 校验通过 | ❌ 校验失败")
void validation() { }@Disabled:禁用测试
跳过某个测试,但不影响其他测试:
java
@Disabled("JDK 17 以下暂不支持此特性")
@Test
void testNewFeature() { }@Tag:测试分组
把测试按类别分组,CI 里可以按组选择跑哪些:
java
@Tag("unit")
@Test
void unitTest1() { }
@Tag("integration")
@Test
void integrationTest1() { }
@Tag("slow")
@Test
void slowTest() { }在 Maven 中过滤:
bash
mvn test -Dgroups=unit # 只跑 unit 组
mvn test -DexcludedGroups=slow # 排除 slow 组@Nested:嵌套测试
用嵌套类组织相关测试,结构更清晰:
java
class UserServiceTest {
@Nested
@DisplayName("保存用户")
class SaveUserTests {
@Test
@DisplayName("成功保存")
void saveSuccess() { }
@Test
@DisplayName("用户名为空则抛异常")
void saveWithEmptyName_ThrowsException() { }
}
@Nested
@DisplayName("查询用户")
class GetUserTests {
@Test
@DisplayName("用户存在则返回")
void getExistingUser() { }
@Test
@DisplayName("用户不存在则抛异常")
void getNonExistingUser_ThrowsException() { }
}
}总结
| 注解 | 作用 |
|---|---|
| @Test | 声明测试方法 |
| @BeforeAll / @AfterAll | 全类级别,只执行一次(必须是 static) |
| @BeforeEach / @AfterEach | 每个测试方法前后执行 |
| @DisplayName | 自定义测试名称 |
| @Disabled | 跳过测试 |
| @Tag | 测试分组 |
| @Nested | 用嵌套类组织测试 |
注解只是工具,理解测试生命周期才是根本。
