@testinstance 是 junit 5 中控制测试类实例生命周期的注解,默认 per_method 每个测试方法新建实例以保障隔离;per_class 则复用单个实例提升性能但需注意线程安全、状态清理及@beforeall/@afterall 的静态要求。

@TestInstance 是 JUnit 5 中用于控制测试类实例创建时机和生命周期的注解,它决定了每个测试方法执行时是否复用同一个测试类实例,还是每次新建一个实例。默认情况下(JUnit 5.4+),测试类采用 PER_METHOD 策略,即每个 @Test 方法都运行在**全新的测试类实例**上 —— 这与 JUnit 4 的行为一致,也更利于测试隔离。
为什么需要调整测试实例策略?
默认的 PER_METHOD 虽安全,但可能带来额外开销(如重复初始化昂贵资源);而 PER_CLASS 允许在类级别共享状态(比如一次启动服务器、加载配置),适合需要跨测试方法复用的场景。但要注意:共享实例意味着测试间可能相互影响,必须确保线程安全、无副作用、手动清理(如用 @BeforeAll/@AfterAll)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
两种可用策略及写法
目前 @TestInstance 支持两个枚举值:
-
TestInstance.Lifecycle.PER_METHOD(默认):每个测试方法前创建新实例,方法后丢弃。无需显式标注。 -
TestInstance.Lifecycle.PER_CLASS:整个测试类只创建一个实例,所有@Test、@BeforeEach、@AfterEach都复用该实例。需显式声明:
class MyTestClass {
private Server server;
@BeforeAll
void startServer() {
server = new Server().start(); // 在类实例创建后、任何测试前执行
}
@Test
void testA() { /* 使用 server */ }
@Test
void testB() { /* 复用同一个 server 实例 */ }
@AfterAll
void stopServer() {
server.stop();
}
}
使用 PER_CLASS 时的关键注意事项
-
@BeforeAll和@AfterAll方法必须是 static(除非测试类实例是单例,即用了PER_CLASS)—— 因为它们在类级别运行,不依赖具体实例。但在PER_CLASS下,它们也可以是非 static 的(此时会绑定到那个唯一的实例上)。 - 不能在
@BeforeEach/@AfterEach中重新赋值实例字段来“模拟重置”,因为对象是共享的;应显式清理状态(如清空集合、关闭连接等)。 - 如果测试类被多个线程并发执行(如启用并行测试),
PER_CLASS必须保证所有共享字段和逻辑线程安全。 - IDE 或构建工具(如 Maven Surefire)通常默认串行执行测试;若开启并行,务必验证
PER_CLASS行为是否符合预期。
什么时候不该用 PER_CLASS?
当测试方法之间存在隐式依赖、修改了共享字段且未重置、或涉及静态可变状态时,强行使用 PER_CLASS 会导致结果不稳定甚至偶发失败。例如:
- 测试 A 修改了
list.add("x"),测试 B 假设list为空 → 失败 - 某个
@BeforeEach方法本该重置字段,却忘了写,而你又依赖了PER_CLASS→ 状态残留 - 使用了第三方库(如 Mockito)的静态 API,且未在
@AfterEach中重置 → 污染后续测试
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










