You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在每个JUnit5动态测试执行后运行特定代码?

解决JUnit5动态测试后执行特定代码(截图)的问题

我明白你的困扰——你实现了TestExecutionListener但没触发executionFinished,而且想在动态测试结束后执行截图逻辑。咱们一步步来解决这个问题:

为什么你的Listener没生效?

你在@BeforeEach里手动创建Launcher并注册listener的做法是无效的,因为这个手动创建的Launcher不是Spring Boot/JUnit平台实际用来运行测试的那个实例。JUnit平台在启动时会自己初始化Launcher,你手动创建的完全是另一个对象,所以你的listener根本不会被调用到。

方案1:通过配置文件注册JUnit Platform的TestExecutionListener

这是注册平台级listener的标准方式,能确保所有测试(包括动态测试)都能触发你的逻辑:

  1. 在src/test/resources目录下创建junit-platform.properties文件
  2. 添加以下配置:
    # 保留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,提问作者Алексей Шнайдмиллер

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:24:39