JUnit 5 注解完整参考
涵盖生命周期、标记、条件执行、嵌套测试等所有注解
生命周期注解
@BeforeAll / @AfterAll
在整个测试类开始/结束时执行,必须是 static 方法。
java
class DatabaseTest {
private static Connection connection;
@BeforeAll
static void initAll() {
// 只执行一次,用于全局初始化
connection = DriverManager.getConnection(DB_URL);
System.out.println("数据库连接建立");
}
@AfterAll
static void cleanupAll() {
// 测试类结束后清理资源
connection.close();
System.out.println("数据库连接关闭");
}
}@BeforeEach / @AfterEach
每个测试方法执行前后运行,非 static。
java
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
// 每个测试前创建新实例,确保测试隔离
calculator = new Calculator();
}
@AfterEach
void tearDown() {
// 释放资源
calculator = null;
}
}执行顺序图
@BeforeAll (static) ──────────────────────────────────▶ @AfterAll (static)
│ ▲
▼ │
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ @BeforeEach │ ──▶│ @Test (Test 1) │ ──▶│ @AfterEach │
└──────────────────┘ └──────────────────┘ └──────────────────┘
│ ▲
▼ │
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ @BeforeEach │ ──▶│ @Test (Test 2) │ ──▶│ @AfterEach │
└──────────────────┘ └──────────────────┘ └──────────────────┘测试标记注解
@Test
标记方法为测试方法,包名:org.junit.jupiter.api.Test
java
@Test
@DisplayName("计算 1 + 1 应返回 2")
void onePlusOneShouldBeTwo() {
assertEquals(2, 1 + 1);
}@DisplayName
自定义测试/类的显示名称,支持中文、emoji、特殊字符。
java
@DisplayName("🧮 计算器功能测试")
class CalculatorTest {
@Test
@DisplayName("➕ 1 + 1 应该等于 2")
void onePlusOneShouldBeTwo() { }
@Test
@DisplayName("➗ 除数不能为零")
void divisionByZeroShouldThrow() { }
}@Disabled
跳过指定的测试或类。
java
@Test
@Disabled("等待修复 #123 后再启用")
void flakyTest() { }
// 整个类禁用
@Disabled("已知问题,暂不使用")
class LegacyIntegrationTest { }@Tag
为测试打标签,用于过滤执行。
java
@Test
@Tag("slow")
void integrationTest() { }
@Test
@Tag("fast")
void unitTest() { }Maven 过滤执行:
xml
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>fast</groups>
<excludedGroups>slow</excludedGroups>
</configuration>
</plugin>嵌套测试
用 @Nested 组织和分组相关测试。
java
@DisplayName("Stack 栈测试")
class StackTest {
private Stack<Object> stack;
@BeforeEach
void setUp() {
stack = new Stack<>();
}
@Nested
@DisplayName("push 操作")
class PushTests {
@Test
@DisplayName("向空栈 push 后大小为 1")
void pushToEmptyStack() {
stack.push("item");
assertEquals(1, stack.size());
}
}
@Nested
@DisplayName("pop 操作")
class PopTests {
@Test
@DisplayName("从空栈 pop 应抛出异常")
void popFromEmptyShouldThrow() {
assertThrows(EmptyStackException.class, stack::pop);
}
}
}动态测试
@TestFactory 动态生成测试用例。
java
@TestFactory
@DisplayName("动态生成矩形面积测试")
Stream<DynamicTest> dynamicTests() {
List<Rectangle> rectangles = List.of(
new Rectangle(2, 3),
new Rectangle(4, 5),
new Rectangle(6, 7)
);
return rectangles.stream()
.map(rect -> DynamicTest.dynamicTest(
String.format("矩形 %d x %d = %d",
rect.width(), rect.height(), rect.area()),
() -> assertEquals(
rect.width() * rect.height(),
rect.area()
)
));
}条件执行注解
@EnabledOnOs / @DisabledOnOs
java
@Test
@EnabledOnOs(OS.LINUX)
void onlyOnLinux() { }
@Test
@DisabledOnOs({OS.WINDOWS, OS.MAC})
void notOnWindowsOrMac() { }@EnabledOnJre / @DisabledOnJre
java
@Test
@EnabledOnJre({JRE.JAVA_17, JRE.JAVA_21})
void java17Or21Only() { }@EnabledIf / @DisabledIf
java
@Test
@EnabledIfSystemProperty(named = "env", matches = "ci")
void onlyInCI() { }
@Test
@EnabledIfEnvironmentVariable(named = "DB_TYPE", matches = "mysql")
void mysqlOnly() { }自定义条件
java
@EnabledIf("customCondition")
boolean customCondition() {
return someRuntimeCheck();
}测试实例生命周期
JUnit 5 支持两种测试实例生命周期:
| 模式 | 说明 |
|---|---|
PER_METHOD(默认) | 每个测试方法创建新实例 |
PER_CLASS | 每个测试类创建单一实例 |
java
@DisplayName("PER_CLASS 生命周期模式")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class PerClassTest {
private int counter = 0;
@BeforeAll
void init() { // 不需要 static
counter = 0;
}
@Test
void first() {
counter++;
assertEquals(1, counter);
}
@Test
void second() {
counter++;
assertEquals(2, counter);
}
}配置方式:
properties
# junit-platform.properties
junit.jupiter.testinstance.lifecycle.default = per_class注解速查表
| 注解 | 作用范围 | 备注 |
|---|---|---|
@Test | 方法 | 标记为测试方法 |
@DisplayName | 类/方法 | 自定义显示名 |
@BeforeAll | 方法 | 类生命周期前(static) |
@AfterAll | 方法 | 类生命周期后(static) |
@BeforeEach | 方法 | 方法生命周期前 |
@AfterEach | 方法 | 方法生命周期后 |
@Nested | 非 static 类 | 嵌套测试类 |
@Tag | 类/方法 | 测试分组标签 |
@Disabled | 类/方法 | 禁用测试 |
@TestFactory | 方法 | 动态测试工厂 |
@TestTemplate | 方法 | 多次调用模板 |
@RepeatedTest(n) | 方法 | 重复执行 n 次 |
@TestInstance | 类 | 测试实例生命周期 |
相关页面
- **Java\JUnit5-完全指南** - 返回总览
- **Java\JUnit5-断言机制** - 断言详解
- **Java\JUnit5-参数化测试** - 数据驱动
- **Java\JUnit5-最佳实践** - 测试设计模式
#标签 #junit #注解 #annotation #lifecycle #testing