Java语言搭建Web自动化框架学习十三(TestNG监听机制)

需求背景:失败案例进行截图

核心代码

13.1新建Listener包,新建TestRusultListener类

public class TestResultListener extends TestListenerAdapter{
	
	@Override
	public void onTestFailure(ITestResult tr) {
		// TODO Auto-generated method stub
		super.onTestFailure(tr);
		//编写自定义内容
		//filePath命名解决:
		//保存路径,保存在项目文件夹,所以要获取项目路径
		String filePath = System.getProperty("user.dir")+"\\target\\screenshot\\";
		//获取时间戳
		String fileName = System.currentTimeMillis()+".png";
		WebDriverUtils.takeScreenshot(filePath+fileName);
	}
	

}

13.2修改testng.xml,使监听器生效

  <listeners>
  <listener class-name = "监听类路径"></listener>
  </listeners>

需求背景:截图嵌入allure报表

核心代码

13.3新建AllureReportListener类

注意:记得新增的监听类都要去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;
		
	}

问题解决

13.1截图未嵌入报表

忘记加监听配置,testng监听对中加AllureReportListener

需求背景:失败案例重试

核心代码

web自动化不够稳定,提高成功率

13.4新建一个TestRetry

public class TestRetry implements IRetryAnalyzer{

	@Override
	public boolean retry(ITestResult result) {
		// testng框架自带,默认失败不会重试,把返回值改为true,则会重试
		return true;
	}

}

测试案例关联失败监听

	@Test(retryAnalyzer = TestRetry.class)

引发问题:失败则返回为真,如果失败了,就一直重试

13.5增加重试次数逻辑

public class TestRetry implements IRetryAnalyzer{
	Logger logger = Logger.getLogger(TestRetry.class);

	private int maxRetryCount = 2;
	private int currentRetryCount = 0;
	
	@Override
	public boolean retry(ITestResult result) {

		if(currentRetryCount < maxRetryCount) {
			currentRetryCount++;
			logger.info("========================================这是第【"+currentRetryCount+"】次重试===========================");
			return true;
			
		}else {
			return false;
		}
	
	}

}

13.6设置全局失败监听重试

新建一个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);
		}
		
	}
}

问题解决

13.2监听重试和dataprovider多行数据冲突(未解决)

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,接口里也有方法,但是子类实现接口后,必须要重写接口方法,等待子类去实现具体方法体

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值