TestNG报告中标记为跳过的重试测试未被移除,求代码问题排查
问题分析与解决方案
你遇到的核心问题是:重试后的测试记录(标记为SKIPPED的重试尝试)仍被计入TestNG报告统计,导致Jenkins里的测试总数包含冗余的重试记录。你的代码存在以下几个关键问题:
1. 遍历集合时的并发修改异常
直接用增强for循环遍历Set<ITestResult>并执行remove操作,会触发ConcurrentModificationException,导致清理逻辑未完整执行,冗余记录自然无法被移除。
2. 清理逻辑不完整
代码仅处理了SkippedTests,但重试过程中第一次失败的记录会被留在FailedTests中(即使重试后测试通过);同时判断逻辑存在漏洞,无法正确识别重试产生的冗余记录。
修正后的代码
修正后的TestListenerAdapter
package generics; import java.util.Iterator; import java.util.List; import org.testng.ITestContext; import org.testng.ITestNGMethod; import org.testng.ITestResult; public class TestListenerAdapter extends org.testng.TestListenerAdapter { @Override public void onFinish(ITestContext context) { // 清理失败测试中的冗余重试记录 cleanRedundantResults(context.getFailedTests().getAllMethods(), context); // 清理跳过测试中的冗余重试记录 cleanRedundantResults(context.getSkippedTests().getAllMethods(), context); } private void cleanRedundantResults(List<ITestNGMethod> methods, ITestContext context) { for (ITestNGMethod method : methods) { List<ITestResult> results = context.getResults(method); if (results.size() <= 1) { continue; // 仅一条记录,无需清理 } // 保留最后一条结果(重试后的最终状态),移除之前的重试记录 ITestResult finalResult = results.get(results.size() - 1); Iterator<ITestResult> iterator = results.iterator(); while (iterator.hasNext()) { ITestResult result = iterator.next(); if (!result.equals(finalResult)) { // 从对应集合中移除冗余记录 if (result.getStatus() == ITestResult.FAILURE) { context.getFailedTests().removeResult(result); } else if (result.getStatus() == ITestResult.SKIP) { context.getSkippedTests().removeResult(result); } iterator.remove(); } } } } }
补充优化(可选)
如果你的测试是并行执行的,原RetryAnalyzer的retryCount存在线程安全问题,可改为用ThreadLocal存储计数:
package generics; import org.testng.IRetryAnalyzer; import org.testng.ITestResult; public class RetryAnalyzer implements IRetryAnalyzer { private ThreadLocal<Integer> retryCount = ThreadLocal.withInitial(() -> 0); private int maxRetryCount = 1; @Override public boolean retry(ITestResult result) { int currentCount = retryCount.get(); if (currentCount < maxRetryCount) { retryCount.set(currentCount + 1); return true; } retryCount.remove(); // 重置线程变量 return false; } }
额外注意事项
你的testng.xml监听类配置顺序是正确的(注解转换器TestTranformer需在监听类之前加载),无需调整。
内容的提问来源于stack exchange,提问作者dai123456va
相关产品推荐
相关产品推荐

