博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
testNG retry 失败的testcase只需要在xml中配置一个listener即可
阅读量:6708 次
发布时间:2019-06-25

本文共 6816 字,大约阅读时间需要 22 分钟。

问题情况                                                 

先说下问题情况,最近在做testNG与selenium集成做自动化测试的问题。

因为如果将testNG做UI 测试的话,很多情况下可能测试是失败的,但是这些失败可能是一些其他的问题导致的,可能是脚本的问题或者是网络环境不稳定导致的,所以我们需要重新尝试运行这个失败的测试用例。

testNG倒是没有直接的retry testcase的功能,不过它却提供了很多的接口,我们可以实现这些接口来得到retry的效果。

在google上看到淘宝的QA项目组采用Ruby语言将testNG的源代码修改了retry的功能,然后又重新build后这样做的。这是一个solution,但是我不推荐。原因有两个:

1,修改的jar包是针对指定的testNG版本的,所以如果我们需要体验testNG的新版本功能,这个jar可能就需要在源码基本上重新build有点 不太合适,详细地址是:

2,该种修改的方法只能使用在testcase级别上,如果需要针对所有的testNG的testsuite都是用这种特性,可能就需要每个testcase都表明他们是使用这个retry功能,有点代码亢余。像这样在testcase中声明retry的类:

import org.apache.log4j.Logger;import org.testng.Assert;import org.testng.annotations.Test;import com.hp.baserunner.RetryFail;import com.hp.pop.DemoPage;public class DemoRun {    private static Logger log=Logger.getLogger(DemoRun.class);    @Test(retryAnalyzer=RetryFail.class)// 这里声明retry的类,可以看到如果这样每个testcase可能都需要这样做,代码是不是有点多啊 :(    public void demoTest()    {        DemoPage dp=new DemoPage();        dp.demoTest();    }    @Test    public void demoTest2()    {        DemoPage dp2=new DemoPage();        dp2.demoTest2();    }}
 
 
 

   这个就是retrytestcase的一个接口,然后impletment这个接口后实现相应的方法即可:

有一个类 RetryAnalyzerCount  已经实现了以上的这个接口的方法:

package org.testng.util;import org.testng.IRetryAnalyzer;import org.testng.ITestResult;import java.util.concurrent.atomic.AtomicInteger;/** * An implementation of IRetryAnalyzer that allows you to specify * the maximum number of times you want your test to be retried. *  * @author tocman@gmail.com (Jeremie Lenfant-Engelmann) */public abstract class RetryAnalyzerCount implements IRetryAnalyzer {  // Default retry once.  AtomicInteger count = new AtomicInteger(1);  /**   * Set the max number of time the method needs to be retried.   * @param count   */  protected void setCount(int count) {    this.count.set(count);  }  /**   * Retries the test if count is not 0.    * @param result The result of the test.   */  @Override  public boolean retry(ITestResult result) {    boolean retry = false;    if (count.intValue() > 0) {      retry = retryMethod(result);      count.decrementAndGet();    }    return retry;  }  /**   * The method implemented by the class that test if the test   * must be retried or not.   * @param result The result of the test.   * @return true if the test must be retried, false otherwise.   */  public abstract boolean retryMethod(ITestResult result);}

 

所以从上面可以看出,如果直接使用继承这个RetryAnalyzerCount 类还是省不少事,直接就可以使用了。

, , org.testng.internal.IResultListener, org.testng.internal.IResultListener2, ,

上面的是另一个类实现了retry的操作的类。这里不使用。

我们今天所使用的是IRetryAnalyzer 接口的,代码如下:

package com.com.baserunner;    import org.testng.IRetryAnalyzer;    import org.testng.ITestResult;    /**     * @author sumeetmisri@gmail.com     * @modify alterhu2020@gmail.com     * @version 1.0     * @category     *      */    public class RetryFail  implements IRetryAnalyzer    {        private final int m_maxRetries = 1;        private final int m_sleepBetweenRetries = 1000;        private int currentTry;        private String previousTest = null;        private String currentTest = null;        public RetryFail()        {            currentTry = 0;        }        @Override        public boolean retry(final ITestResult result)        {            // If a testcase has succeeded, this function is not called.                    boolean retValue = false;                                // Getting the max retries from suite.           // String maxRetriesStr = result.getTestContext().getCurrentXmlTest().getParameter("maxRetries");           String maxRetriesStr = result.getTestContext().getSuite().getParameter("maxRetries");            int maxRetries = m_maxRetries;            if(maxRetriesStr != null)            {                try                        {                    maxRetries = Integer.parseInt(maxRetriesStr);                }                catch (final NumberFormatException e)                {                    System.out.println("NumberFormatException while parsing maxRetries from suite file." + e);                }            }                       // Getting the sleep between retries from suite.you can from the suite parameter             String sleepBetweenRetriesStr = result.getTestContext().getSuite().getParameter("sleepBetweenRetries");            int sleepBetweenRetries = m_sleepBetweenRetries;            if(sleepBetweenRetriesStr != null)            {                try                        {                    sleepBetweenRetries = Integer.parseInt(sleepBetweenRetriesStr);                }                catch (final NumberFormatException e)                {                    System.out.println("NumberFormatException while parsing sleepBetweenRetries from suite file." + e);                }            }                        currentTest = result.getTestContext().getCurrentXmlTest().getName();                        if (previousTest == null)            {                previousTest = currentTest;            }            if(!(previousTest.equals(currentTest)))            {                currentTry = 0;            }                       if (currentTry < maxRetries &&!result.isSuccess())            {                try                {                    Thread.sleep(sleepBetweenRetries);                }                catch (final InterruptedException e)                {                    e.printStackTrace();                }                currentTry++;                  result.setStatus(ITestResult.SUCCESS_PERCENTAGE_FAILURE);                retValue = true;                                      }            else            {                currentTry = 0;            }            previousTest = currentTest;            // if this method returns true, it will rerun the test once again.                                 return retValue;        }    }

还有一个lisetner需要加入到testNG的配置文件中:

package com.coma.baserunner;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 {    @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);        }    }}

然后在testNG的xml的配置文件中如下配置即可:

 

 
 

以上的配置方法没有任何问题,唯一的缺陷是,运行的时候testNG的报告中会将retry的testcase的次数也计算在内,所以可能造成,运行后的testcase数目不准确,关于这个问题网上也有人在讨论,可是一直都没有得到一个好的接解决。

最近觉得仔细看看testNG的源代码,看看能不能修改下对应的testNG的报告。使得结果显示的testcase数据与实际的一致,retry的testcase只计算最后一次运行成功的。

如果有结果,再更新。。。。。。。Smile

转载于:https://www.cnblogs.com/alterhu/p/3191701.html

你可能感兴趣的文章
授予组件和控件许可权限
查看>>
fortitoken
查看>>
python中的字符串操作
查看>>
四则运算(挑战出题)解答之轮子哥版-2
查看>>
监听器 HttpSessionBindingListener
查看>>
Django学习笔记-2018.11.17
查看>>
列表转字典
查看>>
python Day 1 - 搭建开发环境
查看>>
原来还有这样一个东西,重来不知道过-linux ,ulimit
查看>>
IO多路复用之select总结
查看>>
机器学习基础-Logistic回归1
查看>>
ubuntu14.04/16.04无法设置成中文解决办法
查看>>
Eclipse的Debug各种视图介绍(二)
查看>>
servlet:servletContext简介和方法使用
查看>>
CSS属性 table 的 border-collapse 边框合并
查看>>
P1364 医院设置
查看>>
Winform、WPF、Silverlight、MFC区别与联系
查看>>
装有Win7系统的电脑在局域网不能共享的解决方案
查看>>
Spring系统学习:20180612--aop配置中表达式的写法
查看>>
JavaWeb实战——记录网站上一次访问时间
查看>>