zoukankan      html  css  js  c++  java
  • WebDriver框架之自动运行失败的case

    大家在运行自动化case的时候都会碰到失败的情况,有的时候可能是被测程序有bug,还有就是网络的问题,如果想采取失败的case再运行一次的机制,那么有bug的情况,即使再运行N次还是失败,那么如果是网络的问题,那你再运行一次可能就会执行成功(因为再次运行的话,这时候需要操纵的页面元素会正确的加载进来),这样会大大的加强了自动化脚本的健壮性。接下来通过代码来讲解这个机制的实现过程。

    实际上这个机制是通过testng来实现的,虽然testng没有直接提供这种retry to run fail cases的功能,但是testng提供了实现这种功能的接口,它就是IRetryAnalyzer,一旦实现了接口里的方法retry(),就具备了这种功能,当retry()返回的值是true,那就表明该test是需要再运行一次,反之返回的结果是false,那就不需要再运行了该test了。具体的操作代码如下:

     1 package com.cbmp.utility;
     2 
     3 import org.testng.IRetryAnalyzer;
     4 import org.testng.ITestResult;
     5 import org.testng.Reporter;
     6 
     7 public class RetryAnalyzer implements IRetryAnalyzer {
     8     private int count = 0;
     9     private int maxCount = 2;
    10 
    11     @Override
    12     public boolean retry(ITestResult result) {
    13         if (!result.isSuccess()) {
    14             if (count < maxCount) {
    15                 count++;
    16                 result.setStatus(ITestResult.SUCCESS);
    17                 String message = Thread.currentThread().getName()
    18                         + ": Error in " + result.getName() + " Retrying "
    19                         + (maxCount + 1 - count) + " more times";
    20                 System.out.println(message);
    21                 Reporter.log(message);
    22                 return true;
    23             } else {
    24                 result.setStatus(ITestResult.FAILURE);
    25             }
    26         }
    27         return false;
    28     }
    29 }

    着还不算完事,接着我们需要实现监听的接口IAnnotationTransformer,然后把实现的类赋值给@test的属性RetryAnalyzer,具体代码如下:

     1 package com.cbmp.utility;
     2 
     3 import java.lang.reflect.Constructor;
     4 import java.lang.reflect.Method;
     5 
     6 import org.testng.IAnnotationTransformer;
     7 import org.testng.IRetryAnalyzer;
     8 import org.testng.annotations.ITestAnnotation;
     9 
    10 /**
    11  */
    12 public class RetryListener implements IAnnotationTransformer {
    13 
    14     /* (non-Javadoc)
    15      * @see org.testng.IAnnotationTransformer#transform(org.testng.annotations.ITestAnnotation, java.lang.Class, java.lang.reflect.Constructor, java.lang.reflect.Method)
    16      */
    17     @SuppressWarnings("rawtypes")
    18     @Override
    19     public void transform(ITestAnnotation annotation, Class testClass,
    20             Constructor testConstructor, Method testMethod) {
    21 
    22         IRetryAnalyzer retry = annotation.getRetryAnalyzer();
    23         if (retry == null) {
    24             // annotation.setRetryAnalyzer(RetryAnalyzer.class);
    25             //annotation.setRetryAnalyzer(RetryFail.class);
    26             annotation.setRetryAnalyzer(RetryAnalyzer.class);
    27         }
    28     }
    29 
    30 }

    摘自官网的一个注意项,基于这个说法,我们只能使用该接口来修改@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标签

     1 <suite name="CBMP">
     2     <listeners>
     3       <listener class-name="com.cbmp.utility.RetryListener" />
     4   </listeners>
     5   <test name="cbmp1" preserve-order="true" >
     6         <classes>            
     7                <class name="com.cbmp.testcases.loginTestDemo"> 
     8                </class>
     9         </classes>
    10   </test>
    11 </suite>

    这样当你运行testng的时候,就会运行LoginTestDemo类里的标记为@test的方法,当这些方法失败的时候就会调用RetryListener里的retry方法,当retry的方法返回的结果是true的话就重新运行这些失败的方法,如果返回的是false就不会再运行。还有一个要注意的是,测试方法成功的话是不会调用RetryListener里的retry方法,这个是我在调试的时候发现的机制。


    作为文章的收尾,下面展示的是test的代码片段,里面的断言是故意要失败的,以检测retry机制是否被触发

     1     @Test(dependsOnMethods = "opencbmp", enabled = true)
     2     public void noUserAndPwd(){
     3         try {
     4             
     5             loginpage = PageFactory.initElements(driver,
     6                     LoginPage.class);
     7             loginpage.verifyPageElements("CBMP Login Interface Page");
     8             loginpage.login("admin", "dawda");
     9             
    10             Assert.assertEquals(true, false);
    11 
    12             
    13         } catch (Exception e) {
    14             // TODO: handle exception
    15             System.out.println(e.toString());
    16         }
    17 
    18     }

     待解决的问题:

    • result.setStatus(ITestResult.SUCCESS),把当前失败的测试结果设置为成功,但是一直不能生效,这个问题比较困扰我
    • 当触发retry to run fail case的时候,testng也会把重试运行的case也统计在内,这样就会造成运行后的testcase总数目不准确

     

  • 相关阅读:
    【整理】uclibc,eglibc,glibc之间的区别和联系
    C语言calloc()函数:分配内存空间并初始化——stm32中的应用
    收藏!了解UART总线工作原理看这一篇就够了!
    在stm32开发可以调用c标准库的排序和查找 qsort bsearch
    更少的直接百度,更多的取看API
    Sping中的IOC四种注解的简单记录
    使用for循环还是foreach循环?
    总是要还的
    EL表达式,保留小数点后两位
    如何遍历二叉树
  • 原文地址:https://www.cnblogs.com/testermark/p/3550109.html
Copyright © 2011-2022 走看看