背景
在进行直播间测试时,进行web端性能测试及页面流畅度测试时,需要给直播间中添加500个用户(测试人员指定数据),此部分使用testNg脚本实现。但在用户加入脚本执行过程中,难免会因为依赖前置接口性能问题或者网络问题导致部分用户进入直播间失败,所以优化脚本进行失败用例重新执行
方法构思
1、重写IRetryAnalyzer监听器 retry方法 监听执行过程中失败用例,重写IAnnotationTransformer类中的transform方法,修改testNg默认最大执行次数
2、重写IRetryAnalyzer监听器 retry方法 监听执行过程中失败用例,将失败用例数据使用指定文件保存,最后对这些失败用例统一执行。
两种方法的优缺点
方法1,对于执行机器资源能力要求较低,但其灵活性较差,不利于用户自行决定是否进行失败用例重新执行
方法2,此方法适用于CI流水线需求的操作,但读写次数相对较多,数据量大时对机器规格要求较高。
脚本实现
实现方法1:
重写retry,定义用例运行次数
public class RetryCase implements IRetryAnalyzer {
private Logger logger = Logger.getLogger(String.valueOf(RetryCase.class));
public static int currentCount = 1;//当前重新执行次数
private int maxCount = 3;//允许最大执行次数
@Override
public boolean retry(ITestResult result){
logger.info("当前重试次数是【" + currentCount + "】");
if (currentCount <= maxCount) {
logger.info("当前测试方法【" + result.getName() + "】执行失败,进入失败用例重试模式,正在进行第【" + currentCount + "】次重试");
currentCount++;
return true;
}
return false;
}
}
重写transform方法,用例中引用监听器进行灵活化
public class RetryListener implements IAnnotationTransformer {
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod){
//1.初始化IRetryAnalyzer对象
IRetryAnalyzer iRetryAnalyzer = annotation.getRetryAnalyzer();
//判断测试方法是否设置重跑属性
if (iRetryAnalyzer == null) {
//为空说明用例方法里面未设置重跑,则按照全局设置进行用例重跑
//如果用例方法设置了注解属性retryAnalyzer,则按照注解的重跑
annotation.setRetryAnalyzer(RetryListener.class);
}
}
}
用例:
public class CaseTest {
@Test(retryAnalyzer = RetryCase.class)
public void Test1() {
System.out.println("start");
Assert.assertEquals("success","fail");
System.out.println("test01");
}
}
testng.xml中实现套件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Custom suite">
<test name="autonavi-test-framework-lbs">
<classes>
<class name="com.autonavi.test.framework.aos.userview.footprint.share.CaseTest"></class>
</classes>
</test>
<listeners>
<listener class-name="com.autonavi.test.framework.aos.userview.footprint.share.ListenterUtil.RetryCase"></listener>
<listener class-name="com.autonavi.test.framework.aos.userview.footprint.share.ListenterUtil.RetryListener"></listener>
</listeners>
</suite>
实现方法2:—待修正
创建一个 List 来保存失败的用例数据:
List<String[]> failedTests = new ArrayList<>();
在每个测试方法中使用 TestNG 的 @AfterMethod 注解来捕获结果:
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
@AfterMethod
public void recordTestResult(ITestResult result) {
if (result.getStatus() == ITestResult.FAILURE) {
String[] testData = new String[]{
result.getName(), // 用例ID
result.getThrowable().getMessage() // 错误信息
};
failedTests.add(testData);
}
}
3. 将失败的用例写入 Excel 文件
在所有测试用例执行完后,你需要把失败的用例记录写入 Excel 文件。
使用 Apache POI 库可以轻松地处理 Excel 文件。你需要在你的项目中添加该库的依赖。以下是一个简单的例子,演示如何将失败的用例数据写入 Excel 文件:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
public void writeFailedTestsToExcel() {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Failed Tests");
// 写入表头
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("用例 ID");
headerRow.createCell(1).setCellValue("错误信息");
// 写入失败的用例数据
for (int i = 0; i < failedTests.size(); i++) {
Row row = sheet.createRow(i + 1);
String[] testData = failedTests.get(i);
row.createCell(0).setCellValue(testData[0]);
row.createCell(1).setCellValue(testData[1]);
}
try (FileOutputStream fileOut = new FileOutputStream("FailedTests.xlsx")) {
workbook.write(fileOut);
} catch (IOException e) {
e.printStackTrace();
}
}
4. 重新执行失败的用例
在主方法或测试启动类中,你需要添加逻辑以读取 Excel 文件中的失败用例数据并重新执行这些用例。可以使用 Apache POI 读取 Excel 文件数据,并通过反射或 TestNG 的方法将这些用例重新执行。
5. 整合到测试执行流程中
在 @AfterSuite 或者合适的位置调用 writeFailedTestsToExcel() 方法,确保在所有测试结束后记录失败的用例。