注意:记得新增的监听类都要去xml对应添加listener标签对
public class AllureReportListener implements IHookable{ @Override public void run(IHookCallBack callBack, ITestResult testResult) { // TODO Auto-generated method stub //执行testng的@test注解 callBack.runTestMethod(testResult); //如果@test测试案例结果出现异常,即案例失败 if(testResult.getThrowable() != null) { //调用截图方法,进行截图 saveScreenshot(); } } //嵌入allure报表的通过@Attachment附件功能,可参考allure官网 @Attachment(value = "Page screenshot", type = "image/png") public byte[] saveScreenshot() { return WebDriverUtils.takeScreenshot(); } }对应修改WebDriverUtils类,使返回一个byte数组
//新建一个截图方法返回byte数组,因为allure报表生成需要 public static byte[] takeScreenshot() { //强转,为什么能强转?因为WebDriver extents RemoteWebDriver,而RemoteWebDriver implements TakesScreenshot TakesScreenshot screenshot = (TakesScreenshot)driver; //截图保存成BYTES byte[] arr = screenshot.getScreenshotAs(OutputType.BYTES); return arr; }忘记加监听配置,testng监听对中加AllureReportListener
web自动化不够稳定,提高成功率
测试案例关联失败监听
@Test(retryAnalyzer = TestRetry.class)引发问题:失败则返回为真,如果失败了,就一直重试
新建一个TestRetryListener类,implements IAnnotationTransformer,可以获取到@Test里的注解,并且改变注解值,这个也需要在xml监听标签对中添加
public class TestRetryListener implements IAnnotationTransformer{ @Override public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { //获取testng@test里的RetryAnalyzer注解 IRetryAnalyzer analyzer = annotation.getRetryAnalyzer(); //如果没有这个注解,则设置这个注解为自定义的retry类,这样就实现了针对全部test的重试,而不用一个一个test去添加注解 if(analyzer == null) { annotation.setRetryAnalyzer(TestRetry.class); } } }dataprovider中有多行数据时,多次执行同一个@Test时,会被算成重试。 解决方案:当dataprovider中的一行数据被执行完后,重试次数要恢复到初始值
public class TestRetry implements IRetryAnalyzer{ Logger logger = Logger.getLogger(TestRetry.class); private int maxRetryCount = 2; public static int currentRetryCount = 1; @Override public boolean retry(ITestResult result) { logger.info("==================这是第【"+currentRetryCount+"】次重试==========================="); if(currentRetryCount <= maxRetryCount) { currentRetryCount++; logger.info("==================有运行到重试方法==========================="); return true; }else { return false; } } }修改TestResultListener 类
public class TestResultListener extends TestListenerAdapter{ @Override public void onTestFailure(ITestResult tr) { //省略其他功能重复截图 //dataprovider中一行数据全部重试运行次数达到最大值了也还是失败的话,把失败重试次数置为1,避免下一行数据重试次数计数出问题 TestRetry.currentRetryCount = 1; } @Override public void onTestSuccess(ITestResult tr) { // TODO Auto-generated method stub super.onTestSuccess(tr); // //dataprovider中一行数据运行成功后,把失败重试次数置为1,避免下一行数据重试次数计数出问题 TestRetry.currentRetryCount = 1; } }这样改了代码后,虽然不会把重试次数计算错了,但是遇到多行情况,出错的数据就程序报错,一次都不执行了,耗时的事情先放一放,先捋清楚大块,有空在纠小细节
通过监听功能的学习,写代码更好的理解了java中继承父类和实现接口的一点区别 1>继承父类(别人写好的class),关键字是extends,父类里有很多方法,子类继承后可以直接使用父类方法,如果想针对父类方法个性化,就对应选择重写父类方法 2>实现接口(别人写好的interface),关键字是implements,接口里也有方法,但是子类实现接口后,必须要重写接口方法,等待子类去实现具体方法体