TestNG:二次或三次重跑通过后测试脚本状态及统计异常问题
解决TestNG中IRetryAnalyzer重跑导致测试计数异常的问题
问题根源
IRetryAnalyzer仅负责触发失败测试的重跑逻辑,但TestNG默认会将每一次重跑都视为独立的测试用例统计。比如测试在第3次尝试通过时,系统会显示总执行3次,虽然最终结果里的Total run:1是实际测试用例数,但统计计数会出现混淆。
解决方案
通过结合IAnnotationTransformer(全局绑定重试逻辑)和IReporter(自定义统计逻辑),修正统计结果,避免重跑次数干扰真实测试用例计数。
1. 实现IRetryAnalyzer基础重试类
import org.testng.IRetryAnalyzer; import org.testng.ITestResult; public class RetryAnalyzer implements IRetryAnalyzer { private int retryCount = 0; private static final int MAX_RETRY = 2; // 最多重跑2次,总计3次尝试 @Override public boolean retry(ITestResult result) { if (retryCount < MAX_RETRY) { retryCount++; return true; } return false; } }
2. 用IAnnotationTransformer全局绑定重试
避免在每个测试方法上手动添加@Test(retryAnalyzer = ...)注解:
import org.testng.IAnnotationTransformer; import org.testng.annotations.ITestAnnotation; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class RetryTransformer implements IAnnotationTransformer { @Override public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { annotation.setRetryAnalyzer(RetryAnalyzer.class); } }
3. 实现IReporter自定义统计逻辑
重写统计逻辑,将重跑的测试合并为一次计数:
import org.testng.IReporter; import org.testng.ISuite; import org.testng.ISuiteResult; import org.testng.ITestContext; import org.testng.xml.XmlSuite; import java.util.List; import java.util.Map; public class CustomTestReporter implements IReporter { @Override public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDir) { for (ISuite suite : suites) { Map<String, ISuiteResult> suiteResults = suite.getResults(); for (ISuiteResult result : suiteResults.values()) { ITestContext context = result.getTestContext(); // 统计真实的测试用例数(去重重跑记录) int totalTests = context.getAllTestMethods().length; long failedTests = context.getFailedTests().getAllResults().stream() .filter(res -> !res.isSuccess()) .map(res -> res.getMethod().getMethodName()) .distinct() .count(); long skippedTests = context.getSkippedTests().getAllResults().stream() .map(res -> res.getMethod().getMethodName()) .distinct() .count(); long passedTests = totalTests - failedTests - skippedTests; // 输出修正后的统计数据 System.out.println("=== 修正后测试统计 ==="); System.out.printf("Total run: %d%n", totalTests); System.out.printf("Passed: %d%n", passedTests); System.out.printf("Failed: %d%n", failedTests); System.out.printf("Skipped: %d%n", skippedTests); } } } }
4. 在testng.xml中配置监听器
将Transformer和自定义Reporter加入配置:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite name="RetryTestSuite"> <listeners> <listener class-name="com.yourpackage.RetryTransformer"/> <listener class-name="com.yourpackage.CustomTestReporter"/> </listeners> <test name="CoreTests"> <classes> <class name="com.yourpackage.YourTestClass"/> </classes> </test> </suite>
补充说明
- 上述配置后,自定义报告将按真实测试用例数统计,不会把重跑次数计入总执行数。
- 若使用TestNG自带HTML报告,可修改报告模板或结合ExtentReports等第三方工具,更优雅地展示重跑后的测试结果。
内容的提问来源于stack exchange,提问作者qadhava sharath
相关产品推荐
相关产品推荐

