arrow是testng的一个扩展插件,参考arrow的源代码
1.新建一个工程,结果如图:
2.RetryListener.java的代码
package com.netease.qa.testng; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import org.testng.IAnnotationTransformer; import org.testng.IRetryAnalyzer; import org.testng.annotations.ITestAnnotation; /** * RetryListener for each test method. */ public class RetryListener implements IAnnotationTransformer { @Override public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { System.out.println("transform"); IRetryAnalyzer retry = annotation.getRetryAnalyzer(); if (retry == null) { annotation.setRetryAnalyzer(TestngRetry.class); } } }
3.TestngRetry.java的代码
package com.netease.qa.testng; import org.testng.IRetryAnalyzer; import org.testng.ITestResult; import org.testng.Reporter; import com.netease.qa.testng.utils.ConfigReader; /** * TestNG retry Analyzer.* */ public class TestngRetry implements IRetryAnalyzer { private int retryCount = 1; private static int maxRetryCount; static { ConfigReader config = ConfigReader.getInstance(); maxRetryCount = config.getRetryCount(); } @Override public boolean retry(ITestResult result) { System.out.println("retry"); if (retryCount <= maxRetryCount) { Reporter.setCurrentTestResult(result); retryCount++; return true; } return false; } public static int getMaxRetryCount() { return maxRetryCount; } public int getRetryCount() { return retryCount; } }
4.ConfigReader.java的代码
package com.netease.qa.testng.utils; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Enumeration; import java.util.Properties; /** * Read config.properties file. Get the retrycount,default is 0 if not defined */ public class ConfigReader { private static ConfigReader cr; private int retryCount = 0; private String sourceCodeDir = "src"; private String sourceCodeEncoding = "UTF-8"; private static final String RETRYCOUNT = "retrycount"; private static final String SOURCEDIR = "sourcecodedir"; private static final String SOURCEENCODING = "sourcecodeencoding"; private static final String CONFIGFILE = "config.properties"; private ConfigReader() { readConfig(CONFIGFILE); } public static ConfigReader getInstance() { if (cr == null) { cr = new ConfigReader(); } return cr; } private void readConfig(String fileName) { Properties properties = getConfig(fileName); if (properties != null) { String sRetryCount = null; Enumeration<?> en = properties.propertyNames(); while (en.hasMoreElements()) { String key = (String) en.nextElement(); if (key.toLowerCase().equals(RETRYCOUNT)) { sRetryCount = properties.getProperty(key); } if (key.toLowerCase().equals(SOURCEDIR)) { sourceCodeDir = properties.getProperty(key); } if (key.toLowerCase().equals(SOURCEENCODING)) { sourceCodeEncoding = properties.getProperty(key); } } if (sRetryCount != null) { sRetryCount = sRetryCount.trim(); try { retryCount = Integer.parseInt(sRetryCount); } catch (final NumberFormatException e) { throw new NumberFormatException( "Parse " + RETRYCOUNT + " [" + sRetryCount + "] from String to Int Exception"); } } } } public int getRetryCount() { return retryCount; } public String getSourceCodeDir() { return this.sourceCodeDir; } public String getSrouceCodeEncoding() { return this.sourceCodeEncoding; } /** * * @param propertyFileName * * @return */ private Properties getConfig(String propertyFileName) { Properties properties = new Properties(); try { properties.load(new FileInputStream(propertyFileName)); } catch (FileNotFoundException e) { properties = null; } catch (IOException e) { properties = null; } return properties; } }
5.BaiduTest.java的代码
package com.retry; import org.testng.annotations.Test; import static org.testng.Assert.*; public class BaiduTest { @Test public void testFalse() { assertTrue(false); } }
6.config.properties
#0 means not retry retrycount=2
7.testng.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="suite_login"> <listeners> <listener class-name="com.netease.qa.testng.RetryListener" /> </listeners> <test name="LoginTest"> <classes> <class name="com.retry.BaiduTest" /> </classes> </test> </suite>
设置的每次验证都失败,所以会总共运行3次,前两次为skip,后一次为true,运行结果如下
当引入dataProvider后,从第二组数据开始,运行结果与预期的不符,这个还不知道是什么原因,希望有知道的可以一起分享。