
正文
WebDriver框架之自动运行失败的case
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
大家在运行自动化case的时候都会碰到失败的情况,有的时候可能是被测程序有bug,还有就是网络的问题,如果想采取失败的case再运行一次的机制,那么有bug的情况,即使再运行N次还是失败,那么如果是网络的问题,那你再运行一次可能就会执行成功(因为再次运行的话,这时候需要操纵的页面元素会正确的加载进来),这样会大大的加强了自动化脚本的健壮性。接下来通过代码来讲解这个机制的实现过程。
实际上这个机制是通过testng来实现的,虽然testng没有直接提供这种retry to run fail cases的功能,但是testng提供了实现这种功能的接口,它就是IRetryAnalyzer,一旦实现了接口里的方法retry(),就具备了这种功能,当retry()返回的值是true,那就表明该test是需要再运行一次,反之返回的结果是false,那就不需要再运行了该test了。具体的操作代码如下:
package com.cbmp.utility; import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import org.testng.Reporter; public class RetryAnalyzer implements IRetryAnalyzer {
private int count = 0;
private int maxCount = 2; @Override
public boolean retry(ITestResult result) {
if (!result.isSuccess()) {
if (count < maxCount) {
count++;
result.setStatus(ITestResult.SUCCESS);
String message = Thread.currentThread().getName()
+ ": Error in " + result.getName() + " Retrying "
+ (maxCount + 1 - count) + " more times";
System.out.println(message);
Reporter.log(message);
return true;
} else {
result.setStatus(ITestResult.FAILURE);
}
}
return false;
}
}
着还不算完事,接着我们需要实现监听的接口IAnnotationTransformer,然后把实现的类赋值给@test的属性RetryAnalyzer,具体代码如下:
package com.cbmp.utility; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import org.testng.IAnnotationTransformer;
import org.testng.IRetryAnalyzer;
import org.testng.annotations.ITestAnnotation; /**
*/
public class RetryListener implements IAnnotationTransformer { /* (non-Javadoc)
* @see org.testng.IAnnotationTransformer#transform(org.testng.annotations.ITestAnnotation, java.lang.Class, java.lang.reflect.Constructor, java.lang.reflect.Method)
*/
@SuppressWarnings("rawtypes")
@Override
public void transform(ITestAnnotation annotation, Class testClass,
Constructor testConstructor, Method testMethod) { IRetryAnalyzer retry = annotation.getRetryAnalyzer();
if (retry == null) {
// annotation.setRetryAnalyzer(RetryAnalyzer.class);
//annotation.setRetryAnalyzer(RetryFail.class);
annotation.setRetryAnalyzer(RetryAnalyzer.class);
}
} }
摘自官网的一个注意项,基于这个说法,我们只能使用该接口来修改@test的属性
IAnnotationTransformer only lets you modify a @Test annotation. If you need to modify another TestNG annotation (a configuration annotation, @Factory or @DataProvider ), use an IAnnotationTransformer2 .
最后我们还需要在testng的suite.xml文件添加一个listener标签
<suite name="CBMP">
<listeners>
<listener class-name="com.cbmp.utility.RetryListener" />
</listeners>
<test name="cbmp1" preserve-order="true" >
<classes>
<class name="com.cbmp.testcases.loginTestDemo">
</class>
</classes>
</test>
</suite>
这样当你运行testng的时候,就会运行LoginTestDemo类里的标记为@test的方法,当这些方法失败的时候就会调用RetryListener里的retry方法,当retry的方法返回的结果是true的话就重新运行这些失败的方法,如果返回的是false就不会再运行。 还有一个要注意的是,测试方法成功的话是不会调用RetryListener里的retry方法,这个是我在调试的时候发现的机制。
作为文章的收尾,下面展示的是test的代码片段,里面的断言是故意要失败的,以检测retry机制是否被触发
@Test(dependsOnMethods = "opencbmp", enabled = true)
public void noUserAndPwd(){
try { loginpage = PageFactory.initElements(driver,
LoginPage.class);
loginpage.verifyPageElements("CBMP Login Interface Page");
loginpage.login("admin", "dawda"); Assert.assertEquals(true, false); } catch (Exception e) {
// TODO: handle exception
System.out.println(e.toString());
} }
待解决的问题:
- result.setStatus(ITestResult.SUCCESS),把当前失败的测试结果设置为成功,但是一直不能生效,这个问题比较困扰我
- 当触发retry to run fail case的时候,testng也会把重试运行的case也统计在内,这样就会造成运行后的testcase总数目不准确







