testng重试机制
操作步骤
1.实现(implements)IRetryAnalyzer接口,重写(override)retry方法
2.实现(implements)IAnnotationTransformer接口,重写(override)transform方法
3.在testng.xml文件中设置监听
实现步骤
新建一个类TestCaseRetry,implements IRetryAnalyzer接口。该类的作用是设定失败的用例重跑需要重新运行的次数,设定一个运行次数,设定一个最大执行次数,当运行次数超过最大执行次数的时候,说明重跑完成。
retry方法返回值如果为true说明重跑未完成,返回值为false,说明重跑完成
public class TestCaseRetry implements IRetryAnalyzer { private Logger logger = Logger.getLogger(TestCaseRetry.class); //当前正在进行的重试次数 public static int currentCount = 1; //允许重试的最大次数 private int maxCount = 2; @Override //如果返回为true的话,则执行retry public boolean retry(ITestResult iTestResult) { logger.info("当前重试次数是【" + currentCount + "】"); if (currentCount <= maxCount) { logger.info("当前测试方法【" + iTestResult.getName() + "】执行失败,进入失败用例重试模式,正在进行第【" + currentCount + "】次重试"); currentCount++; return true; } return false; } }
新建一个类RetryListener,implements IAnnotationTransformer接口。该类的作用是用来监听所有的测试方法是否有retryAnalyzer注解属性,如果有该属性则不会执行我们设定的重跑机制(局部重跑的优先级比全局的高)。
public class RetryListener implements IAnnotationTransformer { @Override public void transform(ITestAnnotation iTestAnnotation, Class aClass, Constructor constructor, Method method) { //1.初始化IRetryAnalyzer对象 IRetryAnalyzer iRetryAnalyzer = iTestAnnotation.getRetryAnalyzer(); //判断测试方法是否设置重跑属性 if (iRetryAnalyzer == null) { //为空说明用例方法里面未设置重跑,则按照全局设置进行用例重跑 //如果用例方法设置了注解属性retryAnalyzer,则按照注解的重跑 iTestAnnotation.setRetryAnalyzer(TestCaseRetry.class); } } }
将监听类RetryListener添加到testng.xml文件中
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="app_auto"> <test name="login"> <classes> <class name="cases.LoginTest"></class> </classes> </test> <!--配置监听器--> <listeners> <!--监听用例执行情况--> <listener class-name="包.CustomListener"></listener> <!--对用例方法执行进行监听是否需要重试--> <listener class-name="包.RetryListener"></listener> </listeners> </suite>
但是运行到这里的时候,会有一个问题:那就是在第一步设定重跑次数的时候,没有设定什么时候把正在重跑的次数(currentCount)还原为初始值,这样就会导致只有在执行第一个失败用例的时候会进行重跑,遇到第二个失败用例,因为当前的运行次数已经超过最大次数了,但是并没有进行还原,所以后面的失败用例永远不会进入重跑。
解决方法:
失败的用例在执行重跑的时候,要么重跑成功,要么依然失败(当前不考虑skip,但是也可以加上),那我们监听用例的执行结果,在用例执行有结果以后,我们重置执行次数就可以了。
新建一个CustomListener类,implements TestListenerAdapter接口,重写其中的onTestFailure和onTestSuccess方法。这两个方法为用例执行以后失败和成功分别调用的方法,比如用例执行失败需要截图,就可以在onTestFailure方法里面去实现,这样用例执行失败以后,会进入该方法完成截图操作。而我们只需要在这两个方法里面将对面的运行重跑次数恢复初始值即可。这样不管重跑几次的失败用例执行结果是成功还是失败都必然会让重跑次数恢复默认值,其他失败用例再次执行重跑的时候就可以不受影响。
public class CustomListener extends TestListenerAdapter { Logger logger = Logger.getLogger(CustomListener.class); @Override public void onTestFailure(ITestResult tr) { super.onTestFailure(tr);//如果测试用例执行完所有重试以后依然失败的话,重新设置currentCount为初始值,方便其他用例执行重试 logger.info("用例执行失败,重试机制的次数恢复初始值"); TestCaseRetry.currentCount = 1; } @Override public void onTestSuccess(ITestResult tr) { //如果测试用例执行重试的时候,执行成功了,也需要设置currentCount为初始值,方便其他用例执行重试 logger.info("用例执行成功,重试机制的次数恢复初始值"); TestCaseRetry.currentCount = 1; super.onTestSuccess(tr); }
}