生命周期怎么走
JUnit 5 默认每个测试方法新建一次测试类实例(PER_METHOD),因此 @BeforeAll/@AfterAll 默认必须是 static;@BeforeEach/@AfterEach 围绕每个方法执行。用 @TestInstance(PER_CLASS) 可改为一类一实例、允许非静态的 @BeforeAll。方法执行顺序默认由确定性但非直观的算法决定,需要顺序时用 @TestMethodOrder 显式声明。
基本信息
| 方法级 | @BeforeEach/@AfterEach:每个测试方法前后各一次 |
|---|---|
| 类级 | @BeforeAll/@AfterAll:整类前后各一次,默认 static |
| 实例策略 | @TestInstance:PER_METHOD(默认)与 PER_CLASS |
| 顺序控制 | @TestMethodOrder 加 @Order,或按方法名排序 |
| 扩展机制 | Extension 回调可替代部分生命周期逻辑 |
| 迁移注意 | JUnit 4 的 @Before/@After 与 5 不同名,注解不要混用 |
配置示例
配置示例
@TestInstance(TestInstance.Lifecycle.PER_CLASS) // 一类一实例
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class OrderFlowTest {
@BeforeAll void initData() { } // PER_CLASS 下可非 static
@BeforeEach void reset() { }
@Test @Order(1) void create() { }
@Test @Order(2) void pay() { }
@AfterAll void cleanup() { }
}典型使用场景
- 昂贵资源只建一次:容器、连接池放到 @BeforeAll
- 数据隔离:@BeforeEach 重置状态,保证用例独立
- 流程型测试:创建到支付到退款用 @Order 显式声明顺序
- 迁移 JUnit 4:逐条映射注解并复盘原依赖顺序的地方
- 防空转:结合超时规则防止用例挂起拖垮流水线
注解执行时机
| 注解 | 时机 | 执行次数 |
|---|---|---|
| @BeforeAll | 全类测试前 | 一次(默认 static) |
| @BeforeEach | 每个方法前 | 每方法一次 |
| @AfterEach | 每个方法后 | 每方法一次,失败也执行 |
| @AfterAll | 全类测试后 | 一次 |
依赖执行顺序的用例本质是流程型测试:能拆开更好;拆不开就显式 @Order 并写明依赖,别赌默认顺序。顺序声明本身也要保持稳定,改动顺序等于改接口。
PER_CLASS 下实例字段跨用例保留:上一条用例的残留状态会污染下一条,前置必须显式重置;并行执行会把这个问题放大成随机失败。
清理逻辑自身要稳:@AfterEach 抛异常会干扰结果统计,清理失败最好降级为告警而不是直接炸掉用例;多个清理步骤要各自捕获异常,确保后续步骤继续执行。