UI自动化测试:异常截图和page_source
自动化测试过程中,是否遇到过脚本执行中途出错却不知道原因的情况?测试人员面临的不仅是问题的复现,还有对错误的快速定位和分析。而异常截图与页面源码(Page Source)的结合,正是解决这一难题的利器。
在实际的自动化测试中,您是否清楚异常发生时的具体页面状态?单凭日志信息往往无法全面还原错误背景。通过自动化实现异常截图和保存页面源码的功能,您可以大幅提升定位问题的效率和准确性。
在UI自动化测试行业,随着业务复杂性增加,定位问题的效率和深度成为测试团队竞争力的核心。以异常截图和页面源码为代表的增强调试工具,已成为优秀测试框架的标配。例如 Allure 的报告集成截图功能,TestNG 的详细异常日志,都表明这种趋势在逐步标准化。
为什么需要异常截图和Page Source?
- 截图直观定位问题:UI界面异常、元素定位失败等问题可通过截图直接查看。
- 源码辅助排查:页面源码保存可帮助分析DOM结构变化、动态加载等问题。
- 联动使用效果更佳:截图展示表面,源码剖析细节,二者结合为测试提供全方位视角。
实际案例分享
例如,使用 Selenium 进行电商网站的自动化测试时,在支付页面的验证中,偶尔会出现按钮未加载的问题。通过启用异常捕获机制,截图显示支付按钮缺失,而源码内容揭示了JS脚本未执行的原因,最终确认问题出在接口超时。
01 场景
-
增加自动化测试代码的可测性
-
丰富报告
02 实现代码异常时
实现代码异常的时候,实现截图和打印page_source
实现方法:try except 配合截图和page_source操作
特别注意1:
-
在保存截图和页面源码时,一定先创建好images、source_path路径
-
保存截图:driver.save_screenshot(路径名称)
-
获取页面源码:driver.page_source()
-
异常处理会影响用例本身的结果;
解决办法:在except之后,再把异常抛出
代码最后加上:raise Exception;
如果用例失败,抛出异常;否则即使捕获到异常,用例也会通过
特别注意2:
-
将截图保存到allure报告中
allure.attach.file(截图路径,name=‘image’,attachment_type=allure.attachment_type.PNG)
-
将页面源码保存到allure中,以文本的形式存储
allure.attach.file(源码路径,name=‘text’,attachment_type=allure.attachment_type.TEXT)
import sys
import timeimport allure
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChainsclass TestBaidu:def setup_class(self):self.driver = webdriver.Chrome()self.driver.implicitly_wait(2)def teardown_class(self):self.driver.quit()def test_baidu(self):self.driver.get('https://www.baidu.com')try:self.driver.find_element(By.ID, 'su1')except Exception:# 时间戳time_stamp = int(time.time())# 注意:一定要创建好images路径、source_path路径image_path = f'./images/image_{time_stamp}.PNG'page_source_path = f'./page_source/page_source_{time_stamp}.html'# 保存截图self.driver.save_screenshot(image_path)# 保存获取到的页面源码with open(page_source_path, 'w', encoding='utf-8') as f:f.write(self.driver.page_source)# 将截图添加到allure报告中allure.attach.file(image_path,name='image',attachment_type=allure.attachment_type.PNG)# 将页面源码添加到allure报告中allure.attach.file(page_source_path,name='text',attachment_type=allure.attachment_type.TEXT)# 如果用例失败,抛出异常;否则即使捕获到异常,用例也会通过raise Exception
03 代码优化
异常捕获处理代码是公共方法和业务代码无关,不能耦合。
解决办法,使用装饰器装饰用例或者相关方法。
思路
-
先把装饰器架子搭建好
-
把相关逻辑嵌套进来
特别注意
使用装饰器执行用例,被装饰函数还没有执行,所以还没有self.driver,获取被装饰方法的self,也就是实例对象,通过self就可以拿到声明的实例变量driver
driver = args[0].driver
前提条件:被装饰的方法是一个实例方法,实例需要有实例变量self.driver
-
解决方法1:获取driver放到函数执行之后
import sys
import timeimport allure
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys# 采用装饰器
def ui_exception_record(func):def inner(*args, **kwargs):try:return func(*args, **kwargs)except Exception:driver = args[0].driver# 时间戳time_stamp = int(time.time())# 注意:一定要创建好images路径、source_path路径image_path = f'./images/image_{time_stamp}.PNG'page_source_path = f'./page_source/page_source_{time_stamp}.html'# 保存截图driver.save_screenshot(image_path)# 保存获取到的页面源码with open(page_source_path, 'w', encoding='utf-8') as f:f.write(driver.page_source)# 将截图添加到allure报告中allure.attach.file(image_path,name='image',attachment_type=allure.attachment_type.PNG)# 将页面源码添加到allure报告中allure.attach.file(page_source_path,name='text',attachment_type=allure.attachment_type.TEXT)# 如果用例失败,抛出异常;否则即使捕获到异常,用例也会通过raise Exceptionreturn inner
class TestBaidu2:def setup_class(self):self.driver = webdriver.Chrome()self.driver.implicitly_wait(2)def teardown_class(self):self.driver.quit()@ui_exception_recorddef test_baidu(self):self.driver.get('https://www.baidu.com')self.driver.find_element(By.ID, 'su1')
-
解决方法2:保证使用装饰器的时候,driver已经声明:driver = args[0].driver
import sys
import timeimport allure
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys# 采用装饰器
def ui_exception_record(func):def inner(*args, **kwargs):driver = args[0].drivertry:return func(*args, **kwargs)except Exception:# 时间戳time_stamp = int(time.time())# 注意:一定要创建好images路径、source_path路径image_path = f'./images/image_{time_stamp}.PNG'page_source_path = f'./page_source/page_source_{time_stamp}.html'# 保存截图driver.save_screenshot(image_path)# 保存获取到的页面源码with open(page_source_path, 'w', encoding='utf-8') as f:f.write(driver.page_source)# 将截图添加到allure报告中allure.attach.file(image_path,name='image',attachment_type=allure.attachment_type.PNG)# 将页面源码添加到allure报告中allure.attach.file(page_source_path,name='text',attachment_type=allure.attachment_type.TEXT)# 如果用例失败,抛出异常;否则即使捕获到异常,用例也会通过raise Exceptionreturn inner
return innerclass TestBaidu2:def setup_class(self):self.driver = webdriver.Chrome()self.driver.implicitly_wait(2)def teardown_class(self):self.driver.quit()@ui_exception_recorddef test_baidu(self):self.driver.get('https://www.baidu.com')self.driver.find_element(By.ID, 'su1')
-
一旦被装饰的方法有返回值,会丢失返回值
解决方案:return func(*args, **kwargs)
当用例执行失败allure报告中可以查看截图
当用例执行失败allure报告中可以查看page_source源码
异常截图和Page Source的结合,不仅帮助测试人员快速还原问题背景,更为问题定位提供了关键依据。这种看似简单的操作,却是提升测试效率的关键一步。
测试的目标从来不是证明程序正确,而是帮助发现问题。学会利用工具,还原问题真相,才是真正的测试之道!
相关文章:

UI自动化测试:异常截图和page_source
自动化测试过程中,是否遇到过脚本执行中途出错却不知道原因的情况?测试人员面临的不仅是问题的复现,还有对错误的快速定位和分析。而异常截图与页面源码(Page Source)的结合,正是解决这一难题的利器。 在实…...

47,【5】BUUCTF web lovesql
进入靶场 可知是单引号闭合,属于字符串型注入 则后续方法与字符串型无异 使用order by 判断出字节数为3 使用union select寻找注入点时切记第一个select为空 库名geek 表名group_concat(table_name) from information_schema.tables where table_schemageek# geek…...

网络安全——常用语及linux系统
一、网络安全概念及法规 网络安全:网络空间安全 cyber security 信息系统:由计算机硬件、网络和通信设备、计算机软件、信息资源、信息用户和规章制度组成的已处理信息流为目的的人机一体化系统 信息系统安全三要素(CIA) 保密…...
json().get() 和 json[““] 的区别
以下是 json().get() 和 json[“”] 的区别: 使用方法和语法 json[“”]: 这是使用字典的索引操作符 [] 来访问 JSON 数据。假设 json 是一个字典,你可以通过 json[“key”] 的方式来获取对应 key 的值。 示例: python import js…...
深入解析CSS属性值计算:从声明到渲染的完整流程
目录 引言1. 确定声明值2. 层叠冲突3. 使用继承4. 使用默认值总结 引言 在网页开发中,理解CSS属性值的计算过程对于开发者来说至关重要。它不仅影响页面样式的最终呈现,还涉及到浏览器如何解析和应用样式规则。本文将深入探讨从无属性值到每个属性都有…...

npm发布工具包+使用
1.初始化package包 npm init -y {"name": "common-cjs-tools","version": "1.0.0","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" &&…...

28:CAN总线入门一:CAN的基本介绍
CAN总线入门 1、CAN总线简介和硬件电路1.1、CAN简要介绍1.2、硬件电路1.3、CAN总线的电平标准 2、帧格式2.1、数据帧(掌握)2.2、遥控帧(掌握)2.3、错误帧(了解)2.4、过载帧(了解)2.5…...

RK3568平台(音频篇)lineout无声调试
一.声音硬件框架 硬件HP_MUTE已强制拉低。 二.设备树配置 es8388_sound: es8388-sound {status = "okay";compatible = "rockchip,multicodecs-card";rockchip,card-name = "rockchip-es8388";hp-det-gpio = <&gpio1 RK_PD2 GPIO_ACT…...

ros2-7.5 做一个自动巡检机器人
7.5.1 需求及设计 又到了小鱼老师带着做最佳实践项目了。需求:做一个在各个房间不断巡逻并记录图像的机器人。 到达目标点后首先通过语音播放到达目标点信息, 再通过摄像头拍摄一张图片保存到本地。 7.5.2 编写巡检控制节点 在chapt7_ws/src下新建功…...

服务器下发任务镭速利用变量实现高效的大文件传输效率
在分布式系统和自动化部署场景中,任务下发往往伴随着大量的文件传输需求。为了提高文件传输的效率,本文将介绍如何巧妙地利用变量来优化任务下发过程中的文件传输。我们将介绍几种方法,通过合理利用变量来减少传输负担、提升传输速度…...
本地用docker装mysql
目录 拉取镜像查看镜像 启动容器查看运行中的容器连接到 MySQL 容器其他一些操作 装WorkBench链接mysql——————————————允许远程登录MySql 拉取镜像 docker pull mysql查看镜像 docker image lsREPOSITORY TAG IMAGE ID CREATED SIZE mysq…...
前端canvas对象转成file对象
import html2canvas from html2canvasexport default {methods: {//canvas对象转成file对象canvasToFile() {html2canvas(this.$parent.$refs[mapPanel].$el,{width: this.$parent.$refs[mapPanel].$el.clientWidth - 600// height:}).then(canvas > {const base64Data can…...
mermaid大全(语法、流程图、时序图、甘特图、饼图、用户旅行图、类图)
⚠️ 有些网站的mermaid可能不完整,因此下面教程中可能有些语法是无效的。 😊亲测Typora软件均可以显示。 1. 介绍 Mermaid是一个基于JavaScript的图表绘制工具,它使用类似Markdown的语法来创建和修改各种类型的图表。以下是关于Mermaid的详…...

运行fastGPT 第四步 配置ONE API 添加模型
上次已经装好了所有的依赖和程序。 下面在网页中配置One API ,这个是大模型的接口。配置好了之后,就可以配置fastGPT了。 打开 OneAPI 页面 添加模型 这里要添加具体的付费模型的API接口填进来。 可以通过ip:3001访问OneAPI后台,**默认账号…...

Spring Initializr创建springboot项目 “java: 错误: 无效的源发行版:19”
我用的1.8的jdk,排查发现这是jdk和springboot版本冲突导致的。 1、File->Project Structure->Project Settings->Project,把language level改成相应的版本 2、File->Project Structure->Module,source和dependancies改成相应的版本 3、F…...

Java IDEA中Gutter Icons图标的含义
前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂,风趣幽默",感觉非常有意思,忍不住分享一下给大家。 👉点击跳转到教程 前言: 很多人刚开始用IDEA来学习编程,会发现下面这些图标。 但是…...
如何进行域名跳转与域名重定向的综合指南
文章摘取于 Dynadot官方博客内容。 在访问一些商业网站时,我们通常会发现这些平台会将多个域名都指向到同一个内容界面。当然,也存在网站迁移到新域名,旧域名则指向新域名以及其内容页面的情况。 这两者实际上都属于域名跳转的范畴ÿ…...
YOLOv10-1.1部分代码阅读笔记-build.py
build.py ultralytics\data\build.py 目录 build.py 1.所需的库和模块 2.class InfiniteDataLoader(dataloader.DataLoader): 3.class _RepeatSampler: 4.def seed_worker(worker_id): 5.def build_yolo_dataset(cfg, img_path, batch, data, mode"train"…...

redux 结合 @reduxjs/toolkit 的使用
1,使用步骤 使用React Toolkit 创建 counterStore(store目录下) --> 为React注入store(src下面的index) --> React组件使用store中的数据(组件) 2,例如下面有一个简单加减的…...
tui-editor报错
原因: 原先的tui-editor插件(富文本编辑器插件)换了个名称,现在已经更名为toast-ui/editor因此安装不了,从而报错! 解决: 1.首先将package.json中的tui-editor那一行修改为 "toast-ui/…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...