tester_ggf资料

本文主要介绍tester_ggf资料 方法和在新技术下所面对的“挑战”,方便大家深入理解tester_ggf资料 过程。本文也将分享tester_ggf资料 所遇到的问题和应对策略,怎么解决怎么做的问题。
通过深入本文可以理解代码原理,进行代码文档的下载,也可以查看相应 Demo 部署效果。

问题背景

在使用 testng 执行 UI 自动化用例时,由于 UI自动化的不稳定性,我们在测试的时候,往往会加上失败重跑机制。在不使用 @DataProvider 提供用例参数化时,是不会有什么问题,如果使用了的话就会出现多条用例都是失败时,重跑机制只会执行第一次失败的用例,其他用例的失败重跑就不执行了。

如下:提供的两组参数都是失败时!(重跑的次数设置为2次)

tester_ggf

从上图中可以看出,第一次失败的用例有重跑了2次,第二次失败的用例就没有重跑2次。

TestNg重跑机制代码实现

TestNg提供的重跑机制,实现思路如下:

  • 创建一个实现类,实现 IRetryAnalyzer 接口,重写该接口的 retry方法,定义失败重跑的规则。
  • 创建一个实现类,实现 IAnnotationTransformer 接口,重写接口 transform 方法,用于监听所有的@Test 注解的测试方法。
  • 在 TestNg 的 xml 文件中配置监听。

创建 IRetryAnalyzer 实现类

package com.ggf.testng.listener;  import org.testng.IRetryAnalyzer; import org.testng.ITestResult;  /**  * @Description: 失败重试方法  *  用来监听用例的执行情况,如果断言失败,或者代码出现错误了  *  都会被这个方法进行捕获到,然后通过返回值来判断是否进行重试。  * @Author: ggf  * @Date: 2020/07/20  */ public class TestngRetry implements IRetryAnalyzer {     /**      * 最大的重跑次数      * 设置用例最多重跑多少次      */     private int maxRetryCount = 2;     /**      * 当前的重跑的次数      */     private int currentRetryCount = 1;     /**      * 复写 IRetryAnalyzer 的方法,所有的用例执行完后的结果都会      * 封装到这个对象ITestResult 传入到 retry.xml 方法,通过这个方法      * 返回值来判断是否需要重新执行用例。false :不重跑  true:重跑。      * @param iTestResult      * @return      */     @Override     public boolean retry(ITestResult iTestResult) {         //如果retry方法返回为true--》执行重试机制         //如果返回是为false --》不会去执行重试         //什么时候会运行到这里??条件-->测试用例执行失败         if(currentRetryCount <= maxRetryCount){             //运行了一次重试机制之后,我们就加1             //如果运行第一次重试机制-->用例执行成功了,用例的结果是pass的             //如果运行第一次重试机制-->用例执行成功了,第二次重试机制不会运行             System.out.println("重跑第【"+currentRetryCount+"】次!");             currentRetryCount++;             return true;         }else{             return false;         }     } }  

创建 IAnnotationTransformer 实现类

package com.ggf.testng.listener;  import org.testng.IAnnotationTransformer; import org.testng.IRetryAnalyzer; import org.testng.annotations.ITestAnnotation;  import java.lang.reflect.Constructor; import java.lang.reflect.Method;  /**  * @Description:  * 由于在使用重跑机制的时候需要在每个用例@Test注解添加 retryAnalyzer 属性。  * 如果用例量过大的话,非常的麻烦,所以我们引入 testng 提供的监听器类:IAnnotationTransformer  * 通过这个监听器类来实现,动态的修改@Test注解属性,我们就可以统一给 @Test 注解动态加上属性retryAnalyzer 值。  * @Author: ggf  * @Date: 2020/07/20  */ public class RetryListener implements IAnnotationTransformer {     @Override     public void transform(ITestAnnotation iTestAnnotation, Class aClass, Constructor constructor, Method method) {         //1、拿到@test注解的retryAnalyzer属性对象         IRetryAnalyzer iRetryAnalyzer = iTestAnnotation.getRetryAnalyzer();          //2、如果@test的retryAnalyzer属性没有设置,iRetryAnalyzer-->null         if(iRetryAnalyzer == null){             iTestAnnotation.setRetryAnalyzer(TestngRetry.class);         }     } }  

xml 文件配置监听器

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >  <suite name="retry">     <test name="retryTest">         <classes>             <class name="com.ggf.testng.listener.RetryDemo"></class>         </classes>     </test>      <listeners>         <!--失败重试监听器-->         <listener class-name="com.ggf.testng.listener.RetryListener"></listener>     </listeners>  </suite>  

测试类

package com.ggf.testng.listener;  import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test;  /**  * @Description:  * @Author: ggf  * @Date: 2020/07/20  */ public class RetryDemo {     @Test(dataProvider = "data")     public void testRetry(String data1, String data2) {         // 断言两个参数是否一样         Assert.assertEquals(data1, data2);     }      @DataProvider     public Object[][] data() {         // 提供两组测试参数         return new Object[][]{{"111","123"}, {"123", "1234"}};     } }  

失败用例重跑问题重现

对于一个使用了dataProvider的用例,因为这个用例是一个标记为@Test的方法,会共用TestngRetrycurrentRetryCount,即整个方法的所有参数化用例,总共只会重跑 2 次。例如一个参数化用例有 2 组参数,如果全部正确,每个用例只会输出一次:

Test1: success Test2: success 

如果两组参数的用例都失败了,对于第一组参数是会重跑2次的(代码设置的是2次,不包含第一次),到了第二组参数就不会继续重跑了,因为currentRetryCount在第一组参数用例跑完,当前值就为 3 了,这个时候不满足重跑条件,第二组参数用例失败后就不会重跑了。

Test1: failed -> skipped Test1: failed -> skipped Test1: failed Test2: failed Test2: failed 

至于这里的 Test2 为什么会跑 2 次,没搞明白,正常来说应该是跑一次的,因为程序中 if(currentRetryCount <= maxRetryCount) ` 满足才会重跑,但是这里是 false 所以不会重跑才对。如果有大神们知道为什么,希望不吝赐教,留个言。。。

问题解决方案

要解决上述的问题,需要在每组参数化用例结束(无论成功,失败)后,重置 currentRetryCount 的值,让当前的次数保持在初始化的状态。

在实现类 TestngRetry 中加上一个重置的方法,如下:

package com.ggf.testng.listener;  import org.testng.IRetryAnalyzer; import org.testng.ITestResult;  /**  * @Description: 失败重试方法  *  用来监听用例的执行情况,如果断言失败,或者代码出现错误了  *  都会被这个方法进行捕获到,然后通过返回值来判断是否进行重试。  * @Author: ggf  * @Date: 2020/07/20  */ public class TestngRetry implements IRetryAnalyzer {     /**      * 最大的重跑次数      * 设置用例最多重跑多少次      */     private int maxRetryCount = 2;     /**      * 当前的重跑的次数      */     private int currentRetryCount = 1;     /**      * 复写 IRetryAnalyzer 的方法,所有的用例执行完后的结果都会      * 封装到这个对象ITestResult 传入到 retry.xml 方法,通过这个方法      * 返回值来判断是否需要重新执行用例。false :不重跑  true:重跑。      * @param iTestResult      * @return      */     @Override     public boolean retry(ITestResult iTestResult) {         //如果retry方法返回为true--》执行重试机制         //如果返回是为false --》不会去执行重试         //什么时候会运行到这里??条件-->测试用例执行失败         if(currentRetryCount <= maxRetryCount){             //运行了一次重试机制之后,我们就加1             //如果运行第一次重试机制-->用例执行成功了,用例的结果是pass的             //如果运行第一次重试机制-->用例执行成功了,第二次重试机制不会运行             System.out.println("重跑第【"+currentRetryCount+"】次!");             currentRetryCount++;             return true;         }else{             return false;         }     }      /**      * 用于重置失败重跑时的次数,还原到初始化的值      * 如果项目中是使用dataProvider注解来提供用例测试数据参数化的,      * 那么每个@Test执行的时候都会共有重跑的次数。      * 例如:一个参数化用例有 3 组参数,如果全部正确,结果是:全部通过      * 如果第一组参数,第一次失败(第二次成功,这里就用掉了一次重跑的次数,currentRetryCount 就+1了)      * 接着第二组参数每次执行都失败,这个时候currentRetryCount=2, 那么第二组参数也就只会执行一次重跑。      */     public void reset() {         currentRetryCount = 1;     } }   

再新建一个监听类 TestngListener , 继承 TestListenerAdapter 类,并重写 onTestSuccessonTestFailure 方法:

package com.ggf.testng.listener;  import org.testng.ITestContext; import org.testng.ITestNGMethod; import org.testng.ITestResult; import org.testng.TestListenerAdapter;  import java.util.Iterator;  /**  * @Description:  * @Author: ggf  * @Date: 2020/07/20  */ public class TestngListener extends TestListenerAdapter {     @Override     public void onTestSuccess(ITestResult iTestResult) {         super.onTestSuccess(iTestResult);         TestngRetry testngRetry = (TestngRetry)iTestResult.getMethod().getRetryAnalyzer();         testngRetry.reset();     }      @Override     public void onTestFailure(ITestResult iTestResult) {         super.onTestFailure(iTestResult);         // 每次dataProvider中的参数跑完一次,就重置一次当前的重跑次数,恢复到默认值,保证每个失败的用例都能重跑设置的次数。         TestngRetry testngRetry = (TestngRetry)iTestResult.getMethod().getRetryAnalyzer();         testngRetry.reset();     } }  

再把新建的TestngListener 监听类,配置到 xml 文件中:

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >  <suite name="retry">     <test name="retryTest">         <classes>             <class name="com.ggf.testng.listener.RetryDemo"></class>         </classes>     </test>      <listeners>         <!--失败重试监听器-->         <listener class-name="com.ggf.testng.listener.RetryListener"></listener>         <!--用例执行结果监听-->         <listener class-name="com.ggf.testng.listener.TestngListener"></listener>     </listeners>  </suite> 

再次执行的结果:

tester_ggf

以上就是对于解决使用了dataProvider用例中的每一个参数化用例,在不重置的情况下,用例重跑次数共用的问题。

最后我们加上重置操作后,失败的用例都会重跑跑 2 次,无论最后成功还是失败,都会重置 TestngRetry 中的currentRetryCount 以保证下一个参数化用例开始时,currentRetryCount 为初始状态。

参考文章:https://ntflc.com/2018/10/18/TestNg-Retry-Failed-Tests-with-DataProvider/

tester_ggf资料部分资料来自网络,侵权毕设源码联系删除

区块链毕设网(www.qklbishe.com)全网最靠谱的原创区块链毕设代做网站
部分资料来自网络,侵权联系删除!
资源收费仅为搬运整理打赏费用,用户自愿支付 !
qklbishe.com区块链毕设代做网专注|以太坊fabric-计算机|java|毕业设计|代做平台 » tester_ggf资料

提供最优质的资源集合

立即查看 了解详情