如何在每个JUnit5动态测试执行后运行特定代码?
解决JUnit5动态测试后执行特定代码(截图)的问题
我明白你的困扰——你实现了TestExecutionListener但没触发executionFinished,而且想在动态测试结束后执行截图逻辑。咱们一步步来解决这个问题:
为什么你的Listener没生效?
你在@BeforeEach里手动创建Launcher并注册listener的做法是无效的,因为这个手动创建的Launcher不是Spring Boot/JUnit平台实际用来运行测试的那个实例。JUnit平台在启动时会自己初始化Launcher,你手动创建的完全是另一个对象,所以你的listener根本不会被调用到。
方案1:通过配置文件注册JUnit Platform的TestExecutionListener
这是注册平台级listener的标准方式,能确保所有测试(包括动态测试)都能触发你的逻辑:
- 在
src/test/resources目录下创建junit-platform.properties文件 - 添加以下配置:
# 保留JUnit默认的listener(如果不需要可以设为true) junit.platform.listeners.deactivate.defaults = false # 注册你的自定义listener(替换成你的全类名) junit.platform.listeners.register=com.cdek.qa_auto.utils.CdekJUnitListener
这样JUnit平台启动时会自动加载你的CdekJUnitListener,executionFinished方法就会在每个测试(包括动态测试)结束后被调用了。你可以在这个方法里判断测试结果,执行截图:
@Override public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) { // 只针对失败的测试执行截图 if (testExecutionResult.getStatus() == TestExecutionResult.Status.FAILED) { // 这里写你的截图逻辑 takeScreenshot(); } }
方案2:用JUnit5 Extension机制(更灵活推荐)
如果你想更精细地控制测试生命周期,JUnit5的Extension机制是更好的选择,比如实现AfterTestExecutionCallback,它会在每个测试(包括动态测试)执行后触发:
步骤1:创建自定义Extension类
import org.junit.jupiter.api.extension.AfterTestExecutionCallback; import org.junit.jupiter.api.extension.ExtensionContext; public class ScreenshotExtension implements AfterTestExecutionCallback { @Override public void afterTestExecution(ExtensionContext context) throws Exception { // 判断测试是否失败 if (context.getExecutionException().isPresent()) { // 执行截图逻辑 takeScreenshot(); } } private void takeScreenshot() { // 这里实现你的截图代码 System.out.println("为失败的测试生成截图"); } }
步骤2:在测试类上启用Extension
修改你的JUnit5Test类,添加@ExtendWith注解:
@SpringBootTest @ExtendWith(ScreenshotExtension.class) // 启用自定义Extension public class JUnit5Test { // 你的测试代码保持不变... }
这样每个动态测试执行后,不管成功失败,都会调用afterTestExecution方法,你可以在这里处理截图逻辑。
注意事项
- 不要混淆Spring的
TestExecutionListener和JUnit Platform的TestExecutionListener:前者是Spring测试框架的,后者是JUnit平台的,你的场景用后者或者Extension更合适。 - 动态测试的
TestIdentifier可以通过testIdentifier.getDisplayName()获取测试名称,方便你给截图命名。
内容的提问来源于stack exchange,提问作者Алексей Шнайдмиллер
相关产品推荐
相关产品推荐

