基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(5)失败用例截图与重试

在UI自动化测试用例执行过程中,经常会有很多不确定的因素导致用例执行失败,比如网络原因、环境问题等,所以我们有必要引入重试机制(失败重跑),来提高测试用例执行稳定性。

准备工作:我们在进行失败截图保存到本地的时候,需要用到FileUtils类,该类是在commons-io包下的,所以我们需要先引入依赖:

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
</dependency>

一:失败用例截图:

1、创建一个用例失败截图监听类(TestResultListener,名字自起)实现IHookable接口,实现run方法。 IHookable接口的作用:动态替换每一个被@Test注解标注的方法,即每当运行到@Test注解的方法的时候,就会执行该类的逻辑。

代码如下:

@Override
public void run(IHookCallBack iHookCallBack, ITestResult iTestResult) {//保证@Test注解标注的测试方法能够正常执行iHookCallBack.runTestMethod(iTestResult);//判断用例结果是否异常if(iTestResult.getThrowable() != null){//testResult参数提供了getInstance方法,可以获取当前测试类的实例(对象)BaseTest baseTest = (BaseTest) iTestResult.getInstance();RemoteWebDriver driver = baseTest.driver;//保存到allure报表中saveScreenshotToAllure(takeScreenshotAsByte(driver));//保存到本地takeScreenshot(driver,"test_"+System.currentTimeMillis());}
}

2、在testng.xml文件中添加listener标签使监听器生效,代码如下:

<!--使监听器生效-->
<listeners><listener class-name="com.howentech.listener.TestResultListener"></listener>
</listeners>

 3、在Listener类中添加@Attachment注解方法,将截图保存到allure报表中

@Attachment(value = "screenshot",type = "image/png")
public byte[] saveScreenshotToAllure(byte[] data){//返回的字节数组的数据 作为附件添加到Allure报表中--》@Attachment注解来实现的return data;
}

4、在Listener类中提供生成字节数组的截图数据

/*** 生成字节数组的截图数据* @param driver* @return*/
public byte[] takeScreenshotAsByte(RemoteWebDriver driver){byte[] data = driver.getScreenshotAs(OutputType.BYTES);return data;
}

5、在Listener类中提供生成普通文件的截图数据,用于在本地也生成截图

/*** 生成截图以普通文件的形式,并且保存到本地* @param driver* @param fileName*/
public void takeScreenshot(RemoteWebDriver driver, String fileName){File srcFile = driver.getScreenshotAs(OutputType.FILE);File destFile = new File(System.getProperty("user.dir")+"\\screenshot\\"+fileName+".png");try {FileUtils.copyFile(srcFile,destFile);} catch (IOException e) {e.printStackTrace();}
}

整个失败用例截图类的代码:

package com.howentech.listener;import com.howentech.common.BaseTest;
import io.qameta.allure.Attachment;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.IHookCallBack;
import org.testng.IHookable;
import org.testng.ITestResult;import java.io.File;
import java.io.IOException;/*** @param* @author rebort* @create 2025/07/08* @return* @description**/
public class TestResultListener implements IHookable {@Overridepublic void run(IHookCallBack iHookCallBack, ITestResult iTestResult) {//保证@Test注解标注的测试方法能够正常执行iHookCallBack.runTestMethod(iTestResult);//判断用例结果是否异常if(iTestResult.getThrowable() != null){//testResult参数提供了getInstance方法,可以获取当前测试类的实例(对象)BaseTest baseTest = (BaseTest) iTestResult.getInstance();RemoteWebDriver driver = baseTest.driver;//保存到allure报表中saveScreenshotToAllure(takeScreenshotAsByte(driver));//保存到本地takeScreenshot(driver,"test_"+System.currentTimeMillis());}}@Attachment(value = "screenshot",type = "image/png")public byte[] saveScreenshotToAllure(byte[] data){//使用@Attachment注解来实现的返回的字节数组的数据 作为附件添加到Allure报表中return data;}/*** 生成字节数组的截图数据* @param driver* @return*/public byte[] takeScreenshotAsByte(RemoteWebDriver driver){byte[] data = driver.getScreenshotAs(OutputType.BYTES);return data;}/*** 生成截图以普通文件的形式,并且保存到本地* @param driver* @param fileName*/public void takeScreenshot(RemoteWebDriver driver, String fileName){File srcFile = driver.getScreenshotAs(OutputType.FILE);File destFile = new File(System.getProperty("user.dir")+"\\screenshot\\"+fileName+".png");try {FileUtils.copyFile(srcFile,destFile);} catch (IOException e) {e.printStackTrace();}}}

整个testng.xml的代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite" parallel="tests" thread-count="2"><!--使监听器生效--><listeners><listener class-name="com.howentech.listener.TestResultListener"></listener></listeners><test name="测试"><classes><class name="com.howentech.testcases.TestBaidu3"/></classes></test>
</suite>

下面,我们特意设置用例执行失败,查看用例失败截图是否会生成在allure报表中生成与在本地生成

执行结果:

(1)在本地文件有生成失败用例截图

在allure报表里也有生成失败用例截图:

二:失败用例重试

1、创建用例重试监听类(RetryListener,名字自起)实现testng包下的IRetryAnalyzer类,重写retry方法。

package com.howentech.listener;import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;/*** @param* @author rebort* @create 2025/7/08* @return* @description**/
public class RetryListener implements IRetryAnalyzer {//最大重试次数private int maxRetryCount=3;//当前的重试次数private int currentRetryCount=0;@Overridepublic boolean retry(ITestResult result) {//限制重试的最大次数,否则会进入死循环if(currentRetryCount < maxRetryCount) {//如果当前的重试次数没有达到限制,就去执行重试机制currentRetryCount++;return true;}else {return false;}}
}

2、添加一个全局注解属性修改的类,用于使@Test注解每次都能拥有retryAnalyzer属性,可以减去每个@Test注解都要配置retryAnalyzer属性操作

package com.howentech.listener;import org.testng.IAnnotationTransformer;
import org.testng.IRetryAnalyzer;
import org.testng.annotations.ITestAnnotation;import java.lang.reflect.Constructor;
import java.lang.reflect.Method;/*** @param* @author rebort* @create 2025/7/08* @return* @description**/
public class GlobalAnnotationTransformer implements IAnnotationTransformer {//通过实现IAnnotationTransformer接口可以动态的修改@Test注解的属性public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {// 获取@Test注解的RetryAnalyzer属性对象IRetryAnalyzer iRetryAnalyzer = annotation.getRetryAnalyzer();if (iRetryAnalyzer == null) {annotation.setRetryAnalyzer(RetryListener.class);}}
}

3、在testng.xml中添加listener标签,使得全局注解修改监听类生效

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite" parallel="tests" thread-count="2"><!--使监听器生效--><listeners><listener class-name="com.howentech.listener.TestResultListener"></listener><listener class-name="com.howentech.listener.GlobalAnnotationTransformer"></listener></listeners><test name="测试"><classes><class name="com.howentech.testcases.TestBaidu3"/></classes></test>
</suite>

下面,我们再来看看失败用例是否会重新运行,最大运行4次,由于上面我特意断言每个用例都失败,所以每个用例都应该运行4次:

每次用户执行失败,都会在本地生成失败截图,如下:

allure报表也会有失败截图,并且监听了当前用例失败重跑了几次:

在allure报表中看到Retries被重复执行了3次,点击每一次的执行结果,都会展示错误截图:

至此,失败用例截图与失败用例重试已经集成完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/89038.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/89038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Oracle】centos7静默安装oracle19c

静默安装三步骤&#xff1a; 1、数据库安装db_install.rsp&#xff08;数据库软件安装响应文件&#xff09;2、配置监听netca.rap&#xff08;监听配置响应文件&#xff09;3、建库dbca.rsp&#xff08;建库响应文件&#xff09;安装oracle19c先决条件准备&#xff1a; 1.检查主…

MCP基础知识二(实战通信方式之Streamable HTTP)

介绍 MCP 使用 JSON-RPC 2.0 作为其传输格式。传输层负责将 MCP 协议消息转换为 JSON-RPC 格式进行传输&#xff0c;并将接收到的 JSON-RPC 消息转换回 MCP 协议消息。其中SSE被废弃了&#xff08;Server-Sent Events (SSE) - Deprecated&#xff09; SSE as a standalone tra…

量子计算与AI的融合:开启智能革命的“量子跃迁”新范式

当量子计算的并行算力与人工智能的深度学习能力相遇,一场颠覆传统认知的技术革命正在酝酿。从药物研发到自动驾驶,从金融风控到气候预测,两者的融合不仅突破了经典计算的算力天花板,更催生出全新的算法范式与产业生态。本文将深入解析量子计算与AI融合的技术逻辑、核心突破…

【氮化镓】不同偏压应力下电荷俘获效应导致的P-GaN HEMT阈值电压不稳定性

2022年12月7日,意大利国家研究委员会微电子与微系统研究所的Giuseppe Greco等人在《Applied Physics Letters》期刊发表了题为《Threshold voltage instability by charge trapping effects in the gate region of p-GaN HEMTs》的文章,基于对p-GaN高电子迁移率晶体管(HEMTs…

ONLYOFFICE深度解锁系列.10-如何识别图像和PDF扫描件中的文本?用ONLYOFFICE的AI OCR轻松搞定!

ONLYOFFICE 文档版本 9.0带来多项 AI 关键改进&#xff0c;显著提升您处理电子表格和 PDF 文件的工作效率。本指南将重点介绍新增的 OCR 功能&#xff0c;并讲解如何在 PDF 编辑器中利用 AI 助手将图像转为可编辑文本。什么是 OCR 文字识别&#xff1f;OCR 技术能够扫描各类文档…

单例模式详解:确保一个类只有一个实例

在软件开发中&#xff0c;设计模式是解决常见问题的经典方案。单例模式&#xff08;Singleton Pattern&#xff09;作为创建型设计模式中最简单也最常用的一种&#xff0c;确保一个类只有一个实例&#xff0c;并提供一个全局访问点。本文将全面探讨单例模式的概念、多种实现方式…

Appdynamic 配置 PostgreSQL 收集器

配置 PostgreSQL 收集器 您可以使用数据库可见性监控任何版本的 PostgreSQL。 连接详细信息 部分场地描述创建新的收集器数据库类型您想要监控的数据库类型。代理人管理收集器的数据库代理。收藏家姓名您想要用来识别收集器的名称。连接详细信息主机名或 IP 地址运行数据库的机…

其他常见 HTTP 方法

除了最常用的四种方法&#xff08;GET、POST、PUT、DELETE&#xff09;&#xff0c;HTTP 协议还定义了一些较少使用但非常有用的请求方法&#xff0c;常用于调试、部分更新、跨域预检等场景。1. HEAD 方法&#xff1a;获取响应头 特点&#xff1a; 用途&#xff1a;与 GET 类似…

Web应用防火墙(WAF)技术

目录 一&#xff1a;简介 1.1 Web安全现状 1.2 传统防御的局限性 二&#xff1a;Web应用防火墙技术解析 2.1 WAF核心架构 2.2 关键技术特性 三&#xff1a;WAF必要性 3.1 典型防护场景 3.2 与传统方案对比 四&#xff1a;进阶防护方案 4.1 智能WAF架构 4.2 关键技术…

机器学习之线性回归(七)

机器学习之线性回归&#xff08;七&#xff09; 文章目录机器学习之线性回归&#xff08;七&#xff09;一、线性回归线性回归超全指南&#xff1a;从“一条直线”到“正则化调参”的完整旅程0. 先对齐语言&#xff1a;标称型 vs 连续型1. 问题形式化2. 损失函数全景3. 求解方法…

基于开源AI大模型、AI智能名片与S2B2C商城小程序源码的用户价值引导与核心用户沉淀策略研究

摘要&#xff1a;在数字化商业生态中&#xff0c;用户留存与核心用户培育是产品成功的关键。本文聚焦开源AI大模型、AI智能名片与S2B2C商城小程序源码的协同应用&#xff0c;探讨如何通过技术赋能实现用户价值引导与核心用户沉淀。研究结合工业品供应链、美妆品牌、健康食品行业…

课题申报书成功率提升85%!借助大模型AI精准选题、搭综述框架及提炼创新点(附实操AI提示词)

大家好,感谢关注。我是七哥,一个在高校里不务正业,折腾用大模型AI实操的学术人。可以添加七哥(qige500)交流学术写作或ChatGPT、Claude等学术大模型AI领域相关问题,多多交流,相互成就,共同进步。 写一份高质量的课题申报书往往面临许多困难,对很多同仁来说,难就难在…

Spring之【写一个简单的IOC容器EasySpring】

目录 EasySpring 注解 EasyAutowired EasyComponent EasyComponentScan EasyLazy EasyPostConstruct EasyProtoType EasyValue Bean定义信息 EasyBeanDefinition 管理Bean定义信息 EasyBeanDefinitionRegister Aware EasyAware EasyBeanFactoryAware EasyBea…

Selenium动态网页爬虫编写与解释

使用Selenium来抓取动态网页。动态网页通常是指那些通过JavaScript动态加载内容的网页&#xff0c;这些内容在初始HTML中并不存在&#xff0c;因此使用传统的requests库无法获取到这些动态生成的内容。Selenium可以模拟浏览器行为&#xff0c;等待JavaScript执行并渲染页面&…

element el-table中使用el-image图片预览被其他表格遮挡

或者::v-deep .el-table__cell {position: static !important;}

MyBatis与Spring整合优化实战指南:从配置到性能调优

一、SqlSessionFactory配置最佳实践 1.1 数据源配置优化 <!-- Spring配置示例 --> <bean id"dataSource" class"com.zaxxer.hikari.HikariDataSource" destroy-method"close"><property name"driverClassName" value&q…

LUA(初学)

条件语句if if then endlocal a 2 if a < 6 thenprint(a) end2条件语句if else if then else endlocal a 2 local b 3 if a > 6 thenprint(a) elseprint(b) end3while循环语句 while do endlocal a 2 while a < 5 doa a 1print(a) end3 4 5for循环语句 for do …

JMeter 连接与配置 ClickHouse 数据库

其他人都需要好几十积分提供jar包&#xff0c;我5积分提供给大家 jar包地址&#xff1a;https://download.csdn.net/download/weixin_41853064/91370401 1、将jar包内的文件放入jmeter/lib/exc目录并重启jmeter 2、配置jmeter JDBC连接 3、复制 click hourse的类名&#xff1…

Kmeams聚类算法详解

文章目录一、聚类任务的简介1.1 聚类的核心特征1.2 聚类的典型应用场景二、Kmeans的思想和数学原理2.1 核心思想2.2 数学原理三、Kmeans计算过程示例3.1 数据集3.2 步骤1&#xff1a;确定K值并初始化簇中心3.3 步骤2&#xff1a;计算样本到簇中心的距离并分配簇3.4 步骤3&#…

平升智慧水务整体解决方案,大数据驱动的智慧水务,让城市供水更智能

平升电子智慧水务整体解决方案 智慧供水整体解决方案&#xff0c;在调度中心搭建智慧水务平台&#xff0c;为供水各环节安装智能测控设备&#xff0c;应用物联网、互联网、大数据、云计算、人工智能等新一代信息技术&#xff0c;构建智慧水务综合管理系统&#xff0c;贯穿从水源…