失败用例的重跑,实践

原创 2015年11月19日 15:08:01

1. 在Testng.xml配置文件,在Test标签下增加监听

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TC_Operation_Suite" parallel="none" preserve-order="true">
<test name="swiftcoder2_0.TC_Operation">
   <groups>
       <run>

     <include name ="test.workflow" /> //执行初始条件
             <include name ="groupa" /> //执行组名为groupa的所有用例
       </run>
   </groups>
<classes>
   <class name = "swiftcoder2_0.TC_Operation" />//要哪个测试用例类,执行以上group
</classes>
<listeners>
   <!-- put the listener class here -->
<listener class-name = "swiftcoder2_0.RetryListener" /> //增加RetryListener的监听

<listener class-name = "swiftcoder2_0.TestngListener" />  //增加TestngListener的监听
   </listeners>
</test> <!-- Test -->

</suite> <!-- Suite -->

2.增加RetryListener类

package swiftcoder2_0;
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{
@Override
public void transform(ITestAnnotation annotation, 
Class testClass, Constructor testConstructor, Method testMethod) {
// TODO Auto-generated method stub
IRetryAnalyzer retry = annotation.getRetryAnalyzer();
if(retry == null){
annotation.setRetryAnalyzer(TestngRetry.class); //设置RetryAnalyzer
}
}

3. 增加TestngRetry类

package swiftcoder2_0;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import org.testng.log4testng.Logger;
import GL.GL;
public class TestngRetry implements IRetryAnalyzer{
private static Logger logger = Logger.getLogger(TestngRetry.class);
private int retryCount = 1;
private static int maxRetryCount;

@Override
public boolean retry(ITestResult result) {
//get the max retry count 
maxRetryCount = Integer.parseInt(GL.getString("maxRunCount")); //在config.properties文件中设置maxRunCount 值
// TODO Auto-generated method stub
if (retryCount <= maxRetryCount) {
String message = "running retry for  '" + result.getName() + "' on class " + this.getClass().getName() + " Retrying "
+ retryCount + " times";
logger.info(message);
retryCount++;
return true;
}

return false;
}

}


4. 增加TestngListener类

package swiftcoder2_0;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import org.testng.log4testng.Logger;
public class TestngListener extends TestListenerAdapter{
private static Logger logger = Logger.getLogger(TestngListener.class);
@Override
public void onTestFailure(ITestResult tr){
super.onTestFailure(tr);
logger.info(tr.getName() + " Failure");
}
@Override
public void onTestSkipped(ITestResult tr){
super.onTestSkipped(tr);
logger.info(tr.getName() + " Skipped");
}
@Override
public void onTestSuccess(ITestResult tr){
super.onTestSuccess(tr);
logger.info(tr.getName() + " Success");
}
@Override
public void onTestStart(ITestResult tr){
super.onTestStart(tr);
logger.info(tr.getName() + " Start");
}
@Override
public void onFinish(ITestContext testContext){
//super.onFinish(testContext);
Iterator<ITestResult> listOfFailedTests = testContext.getFailedTests().getAllResults().iterator();
while(listOfFailedTests.hasNext()){
ITestResult failedTest = listOfFailedTests.next();
ITestNGMethod method = failedTest.getMethod();
if(testContext.getFailedTests().getResults(method).size()>1){
listOfFailedTests.remove();
}else{
if(testContext.getPassedTests().getResults(method).size()>0){
listOfFailedTests.remove();
}
}
}

}

}

5. 设置config.properties文件

maxRunCount=3

6. TC_Operation用例文件

package swiftcoder2_0;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;


import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;


import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;


import org.testng.annotations.BeforeTest;
import org.testng.annotations.Configuration;
import org.testng.annotations.Test;
import swiftcoder2_0.MultiOutputStream;
import swiftcoder2_0.Swiftcoder2_0;
import GL.GL;
import GL.Logs;
import swiftcoder2_0.TestngRetry;
public class TC_Operation {
//@variables
int c =0;
int a =0;
@BeforeTest
@Configuration(beforeTestClass= true, groups = {"test.workflow"})
public void SetUp() throws InterruptedException, IOException{ 
System.out.println("----Before Test--------");

}

@AfterTest
@Configuration(afterTestClass= true, groups = {"test.workflow"})
public void TearDown(){
System.out.println("----After Test--------");
}

@BeforeMethod
@Configuration(beforeTestMethod= true, groups = {"test.workflow"})
public void BeforeMethod() throws InterruptedException{
System.out.println("----Before Method--------");

}
@AfterMethod
@Configuration(afterTestMethod= true, groups = {"test.workflow"})
public  void AfterMethod() throws InterruptedException{
//close the instance of the web driver
GL.quitWebDriver(wd);
System.out.println("----After Method--------");
}
@Test(groups = {"groupa"}, retryAnalyzer = TestngRetry.class)
public void testa(){
a++;
if(a <=2 ){
Assert.fail();
}
System.out.println("testa");
}

@Test(groups = {"groupa"} ,retryAnalyzer = TestngRetry.class
public void testc(){
c++;
if(c <=3){

Assert.fail();

}
System.out.println("testc");
}

@Test(groups = {"groupb"}, retryAnalyzer = TestngRetry.class)
public void testb(){
System.out.println("testb");

}
@Test(groups = {"groupb"}, retryAnalyzer = TestngRetry.class)
public void testb_1(){
System.out.println("testb");

}

}

逻辑分析:

从testng_groups.xml加载RetryListener+TestngListener,2个监听类,在运行每个case后,调用

TestngRetry类和从TestngListener类执行结果,接着 将此结果传入到TestngRetry的retry函数中,如果Fail,当前用例连续执行最大次数为maxRunCount,如果Pass,则不需Retry调用。最后在TestngListener运行结果中删除同一case id no. 的重复用例,对每个用例结果只保留最后运行结果。

7. 运行结果

7.1 如果xml文件不加入TestngListener监听

[TestNG] Running:
  E:\Documents\QA.Management\automation\swiftcoder2_0\testng-groups.xml

----Before Test--------
----Before Method--------
----After Method--------
----Before Method--------
----After Method--------
----Before Method--------
testa
----After Method--------
----Before Method--------
----After Method--------
----Before Method--------
----After Method--------
----Before Method--------
----After Method--------
----Before Method--------
testc
----After Method--------
----After Test--------


===============================================
TC_Operation_Suite
Total tests run: 7, Failures: 5, Skips: 0

7.2 如果xml文件加入TestngListener监听

[TestNG] Running:
  E:\Documents\QA.Management\automation\swiftcoder2_0\testng-groups.xml


This is log file
----Before Test--------
----Before Method--------
----After Method--------
----Before Method--------
----After Method--------
----Before Method--------
testa
----After Method--------
----Before Method--------
----After Method--------
----Before Method--------
----After Method--------
----Before Method--------
----After Method--------
----After Test--------


===============================================
TC_Operation_GroupsSuite
Total tests run: 2, Failures: 1, Skips: 0
===============================================


说明:若需要每个用例,需要监听,需要一一增加@Test(groups = {"groupb"},retryAnalyzer = TestngRetry.class)

如果测试时,用例Fail,最多执行maxRunCount次,用例Pass,无需重跑


xml文件加入TestngListener监听作用:首先解决TestNg生成的index.html文件中个数不对的问题,这个问题只需要在Testng监听器的onFinish方法中,等所有用例运行完之 后,检查用例,按照class+method+dataprodiver的名称生成hashcode获取唯一id,如果fail的用例中存在重复的则在 fail的用例中剔除掉。

参考资料:

http://testng.org/doc/documentation-main.html#test-groups 

TestNG的官网资料 listeners的知识

http://www.ibm.com/developerworks/cn/opensource/os-cn-testinglistener/index.html 
实战 TestNG 监听器
http://www.yeetrack.com/?p=1015
testng增加失败重跑机制
http://testng.org/javadoc/ 

JavaDoc API资料

https://martinholladay.wordpress.com/2013/11/16/testng-adjusting-test-counts-on-retry/

TESTNG & WEBDRIVER – ADJUSTING TEST COUNTS ON RETRY


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

JUnit结果重跑失败用例(支持Mvn和Ant)

1.背景之前一篇文章介绍过 JUnit4—实践三:支持多线程,失败重试执行测试case的方法, 是ant 执行用例结束后,根据输出日志(类似:TEST-com.weibo.cases.suite.H...
  • neven7
  • neven7
  • 2015-04-23 16:02
  • 2118

TestNG实现用例运行失败自动截图和重跑

在前面我的自动化测试框架系列文章中,有一个知识点没有讲到,现在补上。 在运行自动测试脚本时,经常会需要增加失败时自动截图的功能,以及失败重跑功能,下面介绍一下通过监听器的方式来实现自动截图和重跑功能...

解决RobotFramework用例执行失败自动重跑问题

使用自动化脚本进行测试,经常受环境影响等各方面导致本能成功的脚本失败,下面介绍了RFS框架下,失败重跑的方法: 通过改写RobotFramework源代码增加--retry选项,实现test级别的失败...

结合testng实现用例失败重跑

我们在运行自动化测试用例的时候,经常会出现一些异常的情况的情况导致用例失败的问题。所以我们可能会希望对于失败的测试用例再重新运行一次,下来我们来看看结合testng如何使用这个功能 你需要在你的项目中...

testng实现用例失败重跑[修改篇]

testng实现用例失败重跑,对原文做了修改和调整                     原文:结合testng实现用例失败重跑        作者:sai...

JUnit4---实践三:支持多线程,失败重试执行测试case的方法

一.背景 多线程执行用例能很大的节约时间,而JUnit4(org.junit.experimental.ParallelComputer)本身是支持多线程的(以后会专门写一篇介绍JUnit的多线程执行...
  • neven7
  • neven7
  • 2015-02-05 17:06
  • 2195

TestNG监听器实现失败自动截图、重跑、自定义html结果文件功能

本文转载自孔庆云kevin《TestNG监听器实现失败自动截图、重跑、自定义html结果文件功能》 使用Testng框架搭建自动测试框架,经常会需要增加失败自动截图,以及失败重跑功能,下面介绍一...

oracle DBaaS 数据库云服务实践之一添加主机失败解决

错误信息在主机 dfmc-dbaasp-01.dfmc.com.cn 上执行命令 cd /u01/app/oracle/em13c/ADATMP_2017-05-31_14-55-43-PM;/u01...

python的unittest框架用例失败重运行解决方法

当我们在做自动化测试的时候,发现unittest不能支持用例失败自动重运行机制,需要做扩展,达到像java的testng一样支持失败重运行,提高测试质量。 第一个解决方法是,我们使用decorator...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)