selenium - Testng失败后截图和重跑
2018-04-28 本文已影响0人
这不挺好
前言
- 在运行自动化测试脚本时,经常会需要增加失败时自动截图功能,以及失败重跑功能,下面我们通过Testng监听器的方式来实现自动截图和重跑功能。
一、创建一个ResultTest 接口
// ResultTest 接口主要用于实例的转换
public interface ResultTest {
DriverBase DriverBase();
}
// 将所有 Test Case 继承 ResultTest 接口,并 reutrn driverBase 返回
public class CanvasExpressionTest implements ResultTest {
private DriverBase driverBase = new DriverBase("HomeData.BROWSER") ;
@Override
public DriverBase DriverBase() {
return driverBase;
}
}
二、创建一个截图工具类:ScreenshotUtils
/** 截图工具类 */
public class ScreenshotUtils {
private DriverBase driverBase;
public ScreenshotUtils(DriverBase driverBase) {
this.driverBase = driverBase;
}
public void getScreenshot(String methodName) {
// 截图主体功能
File screen = ((TakesScreenshot) driverBase.getDriver()).getScreenshotAs(OutputType.FILE);
// 拼接路径和图片名称
String xpath = "./image/error/" + methodName + "_" + getCurrentTime() + ".png";
File screenFile = new File(xpath);
try {
FileUtils.copyFile(screen,screenFile);
LogUtils.info(" 截图保存路径 ",xpath);
} catch (Exception e) {
LogUtils.error(" 截图保存失败 ",xpath);
e.printStackTrace();
}
}
/** 获取当前时间 */
private String getCurrentTime() {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
return sdf.format(date);
}
}
三、创建一个Java 类并继承 TestListenerAdapter 类
- 在 TestNG 中 TestListenerAdapter为监听器类,主要使用如下方法:
- onStart(ITestContext testContext):在测试类实例化之后,调用任何配置方法之前调用
- onFinish(ITestContext testContext):在所有测试运行并调用其所有配置方法后调用
- onTestStart(ITestResult tr):每次在测试被调用之前调用
- onTestFailure(ITestResult tr):每次测试失败时调用
- onTestSkipped(ITestResult tr):每次跳过测试时调用
- onTestSuccess(ITestResult tr):每次测试成功时调用
想实现 case 运行失败时自动截图,只需要新建一个类 TestNGListener 继承 TestListenerAdapter ,然后重写 onTestFinish、onTestSkipped 等方法,并在这些方法加入截图操作即可
public class TestNGListener extends TestListenerAdapter {
/** 重写 onTestFinish 方法 */
@Override
public void onTestFailure(ITestResult tr) {
LogUtils.error("Test Failure", null);
// 获取示例并转换为 ResultTest
ResultTest result = (ResultTest) tr.getInstance();
// 调用截图方法,并传入方法名称作为图片名称
String methodName = tr.getMethod().getMethodName();
new ScreenshotUtils(result.DriverBase()).getScreenshot(methodName);
}
}
在 TestNG.xml 文件中配置自己编写的监听类
<listeners>
<listener class-name="testng.TestNGListener"/>
</listeners>
四、失败时自动重跑
1. 创建一个 TestngRetry 类并继承 IRetryAnalyzer 接口实现 retry 方法,并实现重跑逻辑
- 返回 true : 代表重跑
- 返回 false :关闭重跑
public class TestngRetry implements IRetryAnalyzer {
private static int retryCount = 1; // 定义重跑次数
private static final int maxRetryCount = 3; // 定义最大重跑次数
@Override
public boolean retry(ITestResult result) {
if (retryCount < maxRetryCount){
LogUtils.error("retryCount" , retryCount);
retryCount ++;
return true;
}
return false;
}
}
2. 添加用例重跑监听器 RetryListener 继承 IAnnotationTransformer 接口实现transform方法,实现用例失败时重跑功能
public class RetryListener implements IAnnotationTransformer {
@Override
public void transform(ITestAnnotation annotation,
Class testClass,
Constructor testConstructor,
Method testMethod) {
IRetryAnalyzer retry = annotation.getRetryAnalyzer();
if (retry == null){
annotation.setRetryAnalyzer(TestngRetry.class);
}
}
}
3. 在TestNG.xml 文件中配置编写的监听器
<listeners>
<listener class-name="testng.TestNGListener"/>
<listener class-name="testng.RetryListener"/>
</listeners>
4. 进一步改进重跑功能
以上三个步骤可以搞定 case 失败时重跑的功能,但是会在结果中会发现失败的 case 会生成多个,显然这样是不好的
// 此时就需要在之前写的 TestNGListener监听器类中重写onFinish 方法
@Override
public void onFinish(ITestContext testContext) {
removeFailed(testContext);
}
private void removeFailed(ITestContext context) {
Iterator<ITestResult> iterator = context.getFailedTests().getAllResults().iterator();
while (iterator.hasNext()) {
ITestResult failedTest = iterator.next();
ITestNGMethod method = failedTest.getMethod();
if (context.getFailedTests().getResults(method).size() > 1) {
iterator.remove();
} else {
if (context.getPassedTests().getResults(method).size() > 0 ){
iterator.remove();
}
}
}