当前位置: 首页 > article >正文

UI自动化测试:异常截图和page_source

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

在实际的自动化测试中,您是否清楚异常发生时的具体页面状态?单凭日志信息往往无法全面还原错误背景。通过自动化实现异常截图和保存页面源码的功能,您可以大幅提升定位问题的效率和准确性。

在UI自动化测试行业,随着业务复杂性增加,定位问题的效率和深度成为测试团队竞争力的核心。以异常截图和页面源码为代表的增强调试工具,已成为优秀测试框架的标配。例如 Allure 的报告集成截图功能,TestNG 的详细异常日志,都表明这种趋势在逐步标准化。

为什么需要异常截图和Page Source?
  1. 截图直观定位问题:UI界面异常、元素定位失败等问题可通过截图直接查看。
  2. 源码辅助排查:页面源码保存可帮助分析DOM结构变化、动态加载等问题。
  3. 联动使用效果更佳:截图展示表面,源码剖析细节,二者结合为测试提供全方位视角。

实际案例分享

例如,使用 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 time

import allure
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains


class 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 time

import 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 Exception

    return 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_record
    def 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 time

import 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].driver

        try:
            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 Exception

    return inner
return 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_record
    def 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的结合,不仅帮助测试人员快速还原问题背景,更为问题定位提供了关键依据。这种看似简单的操作,却是提升测试效率的关键一步。

测试的目标从来不是证明程序正确,而是帮助发现问题。学会利用工具,还原问题真相,才是真正的测试之道!


http://www.kler.cn/a/509026.html

相关文章:

  • LeetCode 707 题:设计链表
  • 代码随想录算法训练营第三十五天-动态规划-01背包(二维)
  • 2024CVPR《HomoFormer》
  • vite工程化
  • 如何保证光谱相机的稳定性和可靠性
  • 简历_使用优化的Redis自增ID策略生成分布式环境下全局唯一ID,用于用户上传数据的命名以及多种ID的生成
  • 模拟练习题
  • BilibiliPotPlayer插件的登录第二天失效,无法看高清视频,要删掉浏览器上的cookie
  • Linux初识:【Linux软件包管理器yum】【Linux编辑器-vim的使用】【Linux编译器-gcc/g++的使用】
  • 精度论文:【Focaler-IoU: More Focused Intersection over Union Loss】
  • 生产环境中常用的设计模式
  • 可部署于所有设备上的开源加速 Stable-Diffusion.cpp:让 AI 图像生成更快、更高效!
  • AI刷题-小R的随机播放顺序、不同整数的计数问题
  • 二叉树总结(hot100)
  • 物联网通信协议对比-带表格
  • R数据分析:有调节的中介与有中介的调节的整体介绍
  • [ Spring ] Install Nacos on Ubuntu24
  • 【汇编语言】直接定址表(一)—— 「从单元标号到跨段数据:解锁汇编语言的隐藏技巧」
  • 【Rust自学】13.4. 闭包 Pt.4:使用闭包捕获环境
  • 信贷业务术语详解:深入理解金融领域的核心概念
  • js常用操作符
  • macOS安装的Ubuntu 20 VM虚拟机扩充磁盘的便捷方式
  • OpenWRT Conserver 共享串口服务实现
  • Linux UDP 编程详解
  • B3DM转换成XYZ
  • AI面试官