首页/开发/软件测试速查/JUnit 5 生命周期与超时
自动化测试66 条

JUnit 5 生命周期与超时

JUnit 5 生命周期回调分方法级(@BeforeEach/@AfterEach)与类级(@BeforeAll/@AfterAll);@TestInstance(PER_CLASS) 让类级回调免写 static,@Timeout 给用例设置执行时长上限。

软件测试速查开发更新于 2026-10-13

生命周期怎么走

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 抛异常会干扰结果统计,清理失败最好降级为告警而不是直接炸掉用例;多个清理步骤要各自捕获异常,确保后续步骤继续执行。

易错点

  • 在 @BeforeEach 里做重活:每条用例重复初始化,测试慢到没人跑
  • 依赖默认方法顺序:版本或并行策略变化后顺序改变,用例集体翻车
  • PER_CLASS 下不重置字段:随机失败难以复现,罪魁是上一条用例的残留
  • @AfterAll 非静态又没配 PER_CLASS:运行直接报错,迁移时最容易踩
  • 静态字段做全局状态:并行执行时用例互相踩踏,失败随机出现难以复现
  • 混用 JUnit 4 与 5 的注解:4 的注解在 5 引擎下静默不执行,前置形同虚设

数据来源与参考

  • JUnit 5 User Guide:Test Instance Lifecycle 与 @Timeout(junit.org)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌