TestNG并行执行后批量重跑失败用例并合并统计结果如何实现
TestNG全量执行完成后统一重跑失败用例方案
核心实现思路
你要的全量用例跑完再统一重跑失败用例、合并结果到单份报告的需求,确实不能靠Retry Analyser实现(Retry是单条用例失败当场重跑,不会等全量跑完),可以通过自定义TestNG监听器+结果合并逻辑实现,步骤如下:
步骤1:自定义监听器收集首次执行的失败用例
实现IExecutionListener和ITestListener双接口,用线程安全的集合存储首次执行的失败用例信息,避免并行执行时的并发问题:
- 定义全局标记区分「首次执行」和「重跑执行」,只收集首次执行的失败用例
- 存储的失败用例要包含完整信息:所属测试类、方法名、参数列表(适配参数化用例)、测试上下文配置
核心代码示例:
import org.testng.*; import org.testng.xml.XmlClass; import org.testng.xml.XmlSuite; import org.testng.xml.XmlTest; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class FailCaseRerunListener implements ITestListener, IExecutionListener { // 线程安全的失败用例存储容器,适配并行执行场景 public static final List<ITestResult> FIRST_RUN_FAILED_CASES = new CopyOnWriteArrayList<>(); // 执行标记:true=重跑阶段,false=首次全量执行阶段 public static boolean IS_RERUN_PHASE = false; @Override public void onTestFailure(ITestResult result) { // 仅首次执行阶段收集失败用例 if (!IS_RERUN_PHASE) { FIRST_RUN_FAILED_CASES.add(result); } } @Override public void onExecutionFinish(ISuite suite) { // 首次执行完成且存在失败用例时触发重跑 if (!FIRST_RUN_FAILED_CASES.isEmpty() && !IS_RERUN_PHASE) { IS_RERUN_PHASE = true; // 构造重跑的TestNG实例 TestNG rerunTestNG = new TestNG(); XmlSuite rerunSuite = new XmlSuite(); rerunSuite.setName("FailedCasesRerunSuite"); XmlTest rerunTest = new XmlTest(rerunSuite); rerunTest.setName("FailedCasesRerunTest"); // 把失败用例组装成重跑的测试类&方法列表 // 此处省略遍历FIRST_RUN_FAILED_CASES构造XmlClass、包含方法的逻辑,可根据自己的用例结构实现 List<XmlClass> rerunClasses = buildRerunClasses(FIRST_RUN_FAILED_CASES); rerunTest.setXmlClasses(rerunClasses); // 启动重跑 rerunTestNG.setXmlSuites(Collections.singletonList(rerunSuite)); rerunTestNG.run(); // 合并两次执行结果 mergeTestResults(suite, rerunTestNG.getSuite()); } } }
步骤2:合并两次执行结果
重写结果合并逻辑,规则如下:
- 首次执行成功的用例,直接保留通过状态
- 首次执行失败的用例,取重跑后的结果作为最终状态:重跑通过则标记为通过,重跑失败才标记为失败
- 不要把两次执行的用例分开统计,确保同一个用例只保留一个最终状态
步骤3:生成单份合并报告
- 如果用TestNG原生报告,直接基于合并后的结果集生成即可
- 如果用Allure等第三方报告,只需要把两次执行的结果都输出到同一个
allure-results目录,重跑的用例结果会自动覆盖首次的失败记录,最终生成的报告自动统计合并后的数值,不需要额外开发
注意事项
- 并行执行场景下,所有共享的存储容器必须用线程安全类,避免并发写入丢数据
- 如果你的用例存在依赖关系,重跑时需要同步把该用例依赖的前置用例也加入重跑列表,避免重跑时因为依赖缺失报错
- 可以根据需要配置重跑次数,比如首次失败后统一重跑1次,还是多次,只需要在重跑逻辑里加循环判断即可
内容的提问来源于stack exchange,提问作者sougata das
相关产品推荐
相关产品推荐

