web自动化-数据驱动与失败用例截图、失败重新运行

因为只有失败的用例需要截图,那么问题就是: 什么时候用例会失败?

数据驱动测试

我们前面覆盖到的用例都是正常的用例,如果要测试异常的用例呢? 我们来写一下登录的异常 场景:【login_page】

# 用户输入框错误提示
#username_error_tips = (By.XPATH,'//div[text()="账号为4~16位字母、数字或下划
线"]')
# 密码输入框错误提示
#password_error_tips = (By.XPATH,'//div[text()="请输入密码"]')

但是这样两种不同的定位表达式去断言就不方便了,我们希望不管是什么的异常,都可以直接 调用一个方法可以实现;所以我们封装一下方法,统一处理输入框异常的提示断言:

  • 都是text= 某个文本,只是文本不一样,所以我们可以把文本参数化一下。到时候用例里是 什么文本,我们就传进去,确认是否存在现实-用is_display方法就可以:
    # 统一处理输入框异常提示断言
     def is_error_tips_display(self, tips_text):
     locator = (By.XPATH, f'//div[text()="{tips_text}"]')
     return self.elememnt_display(locator)

    添加一个测试方法运行异常的登录用例:

    def test_login_failure(open_close_broswer):
     driver = open_close_broswer
     HomePage(driver).click_login_link()
     LoginPage(driver).login("", "lemon123456")
     # 拿到登录失败提示 后断言
     assert_condition(LoginPage(driver).is_error_tips_display("账号为4~16位
    字母、数字或下划线"))

    但是我们异常的用例肯定不止这一条,比如登录失败的用例:

  • 用户名过长: 提示错误

  • 用户名过短: 提示错误

  • 用户名为空,提示错误

  • 密码为空,提示错误 等

像这种,输入数据不一样,而导致结果提示不一样来判断,我们可以用什么来执行?--pytest的数据驱动实现。

#字典列表保存登录异常数据
cases_all = [{'username':'','password':'lemon123456','expected':'账号为
4~16位字母、数字或下划线'},
 {'username':'lemonlemonlemon11','password':'lemon123456','expected':'账
号为4~16位字母、数字或下划线'},
 {'username':'lem','password':'lemon123456','expected':'账号
为4~16位字母、数字或下划线'},
 {'username': 'lemon_auto', 'password': '', 'expected': '请输
入密码'}]
@pytest.mark.parametrize('case', cases_all)
def test_login_fail(open_close_broswer, case):
 driver = open_close_broswer
 HomePage(driver).click_login_link()
 LoginPage(driver).login(case['username'], case['password'])
 # 拿到登录失败提示 后断言
 assert_condition(LoginPage(driver).is_error_tips_display(case['expected']))

但是如果元素定位的方法跟上面的不一样,能加入一起做数据驱动么? 比如 账号密码错误提 示。

  • 不可以,因为方法不一样,不符合数据驱动的原则。数据驱动就是要方法一样 数据不一 样 结果不一样。方法不一样 就不可以数据驱动。

UI自动化测试里数据驱动用的比较少,只有当这种情况才可以做:

  • 1、操作步骤是一致的;不同的输入数据 页面不切换,只是提示错误信息不一样 可以用数 据驱动;如果发生了页面的切换,那么元素定位的步骤又变化了,这种就不太适合数据驱 动了。
  • 2、断言也是一致的,不需要切换页面和另外做元素定位。
    • 所以当用户名密码错误 的提示 这种就不能用数据驱动了,因为元素定位的方式不 一致。要做单独写一条用例去实现
    • 像上面账号密码错误用例要测试就需要单独写一条测试用例执行这个场景的用例。

数据驱动的使用场景总结:

  • 1、数据驱动测试在接口自动化测试里用的更多: 一个方法 数据不一样 获取结果做不同的断言 就可以实现; 
  • 2、UI 自动化测试因为每个用例的步骤和断言的预期结果差异很大,所以一般UI 自动化一般都 不太适合做数据驱动,数据驱动在UI自动化用的比较少;
    • 所以 UI自动化测试 在更多的时候,不会做全用例覆盖,只会做冒烟测试覆 盖,跑正常的用例,或者做基本的配置测试。

自动化的测试数据管理:

  • 1、接口自动化那样具有规则,每个接口的数据都是地址+头部+参数等固定的字段,断言 的方法也可以固定;所以,数据放在excel统一管理,统一读取,统一操作可行性较高;
  • 2、UI自动化测试的测试数据会不会放在外部文件【excel】存放,因为不像接口自动化那 样具有规则,UI的用户名 商品 订单名字啥的没有规则;所以会直接放在py文件脚本里进 行维护管理。

失败用例的截图

UI自动化测试,在用例执行失败时,我们想要更加直观的获取现场的有效信息,通过截图是一 种有效的方式。

  • 因为有界面的测试,有截图是更加直观的。
  • 不需要把每一条用例都截图,只有失败的用例需要定位问题的时候,会去截图;跟我们报 bug一样,失败了截图给开发看。

Seleinum中使用截图有四种方法:我们用第一种和第二种比较多。

from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# 第一种方法: 直接截图保存在本地,传递一个参数:png的图片
driver.save_screenshot("test.png")
# 第二种方法: 将截图保存为本地文件, 后缀都是png的格式 跟上面的方法效果一样的
driver.get_screenshot_as_file("t1.png")
# 第三种方法: 将截图返回为二进制数据 不需要传参 -- 用的不多
print(driver.get_screenshot_as_png())
# 第四种方法: 将截图返回为base64编码的数据 不需要传参 -- 用的不多
print(driver.get_screenshot_as_base64())
driver.close()

因为只有失败的用例需要截图,那么问题就是: 什么时候用例会失败?

  • 参考我们之前的异常捕获: 之前加了异常捕获的位置基本上都会容易发生异常的和失败 的。
  • 所以之前加上异常不会的地方,都可有加上截图。 失败了 直接在根目录 存储一个图片
    class BasePage:
     def __init__(self, driver):
     """初始化函数,定义driver为实例属性
     后面的方法要用就不需要定义参数了,直接调用实例属性即可。
     """
         self.driver = driver
     def wait_element_clickable(self, locator):
         logger.info(f"等待元素{locator}可以点击")
         try:
               web_element=WebDriverWait(self.driver,8,0.5).until(EC.element_to_be_clickable(locator))
                       
         except Exception as e:
             logger.error(f"等待元素超时{e}")
             self.driver.save_screenshot("test.png") # 异常了 就截图
             raise e
         return web_element
     def wait_element_visible(self, locator):
     # web_element代表通过显示等待找到的元素
         logger.info(f"等待元素{locator}可见")
         try:
             web_element = WebDriverWait(self.driver, 8,
    0.5).until(EC.visibility_of_element_located(locator))
         except Exception as e:
            logger.error(f"等待元素可见异常了{e}")
             self.driver.save_screenshot("test.png") # 异常了 就截图
             raise e
         return web_element
    
    

    但是这样做有一个问题: 每个图片的名字一样的,会被覆盖掉。所以要每个名字都独立不一样 的

  • 可以用时间戳区分别,ms级别的时间戳

    import time
    print(int(time.time() * 1000))
    timestamp = f"screenshop_{int(time.time() * 1000)}.png" # 拼接出来图片的名
    字 每次都是不一样的
    print(timestamp)

    还有断言失败 也是要截图的: 所有断言的方法里也要加上截图代码: 但是断言方法里没有driver,可以把driver定义为参数,到时候用例执行的时候存入这个参数。 每一个模块的用例调用断言的方法的时候就加一个driver的参数。

    def assert_equals(driver,actual, excepted):
     try:
         assert actual == excepted
         logger.info(f'断言成功,预期结果:【{excepted}】,实际结果:【{actual}】')
     except Exception as e:
         logger.error(f'断言失败,预期结果:【{excepted}】,实际结果:【{actual}】')
         driver.save_screenshot(f"screenshop_{int(time.time() *1000)}.png") # 异常了 就截图
         raise e
    

    截图都成功了,但是都在根目录下,所以我们希望放在outputs下的单独建一个文件夹目录存 放: screenshot,在路径处理方法里加上截图文件夹的路径处理。

截图和allure报告结合 这样写的截图在框架本地,用例比较多,截图也 比较多,通过时间戳找图片也不太直观和方便,我们想要把截图和用例关联起 来,并体现在测试报告里,目前测试报告里有么?

如果想要把失败截图跟用例关联,附上allure测试报告里,怎么办呢?

  • 用allure 的附件功能加上就可以。allure.attach()
  • allure.attach()把传进去的数据作为allure 的报告的附件添加进去;
  • allure的 attch这个方法不能用本地的图片存储传参数进去,接收的是二进 制格式的数据,所以截图需要用 driver.get_screenshot_as_png() 这个方 法,返回结果是二进制数据。
  • attach方法可以传几个参数:body, name=None, attachment_type=None
    • 1、body:图片的二进制数据: driver.get_screenshot_as_png()
    • 2、name:附件图片取个名字:
    • 3、attachment_type:附件的类型 可以是png bmp等
  • 这样完成后,本地就不会有截图,会在allure文件下产生png的图片,然后 在allure 报告里页面还会展示对应的图片。
  • 注意:要用run运行才会产生allure报告

思考: 接口自动化测试需要失败的截图么?

  • 不需要,接口都没有截图,只有有界面的测试 才需要截图。 【WebUI,APP测试】

失败了重运行(了解)

像UI自动化测试因为不太稳定,很容易失败,所以有同学总是想要失败后重运 行一下用例。

我们的pytest框架是支持失败重运行的功能的:

  • 1、安装与pytest集成的插件:pip install pytest-rerunfailures
  • 2、在运行的命令里加一个参数:
    pytest --reruns 重试次数 (--reruns-delay 次数之间间隔)
    pytest --reruns 2 运行失败的用例可以执行2次
    pytest --reruns 2 --reruns-delay 5 运行失败的用例可以执行2次,每次间隔5秒
    pytest.main([ "-s" , "-v" , "--clean-alluredir" ,f"--alluredir=
    {report_path}" , "-m p0" , "--reruns" , "2" , "--reruns-delay" , "5" ])

    遇到失败的用例,就会自动化重新运行两次。如果重运行通过了 最终的测试报 告里就不会显示失败。

不过失败重运行在工作里不太建议使用:

因为:这实际上是在隐藏问题,而不是暴露问题。测试人员应该关注爆红,而 不是绿色的通过信息, 通过重运行机制,原来产生红色警示的 10几个用例都无 一例外的通过了, 你还会花精力去分析这 10 几个用例失败可能出现的原因 吗?

万一当时确实是在异常的条件下,真的触发了这些用例爆红, 后面因为条件回 复正常,才执行成功呢?如果这种异常条件总是间歇性的出现呢?在这种情况 下,用例重运行隐藏了可能出现的 bug。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vivado设置Vscode为默认编辑器

D:\vscode\Microsoft VS Code\Code.exe -g [file name]:[line number]

开源大模型与闭源大模型:谁将引领AI的未来?

前言 在AI领域,开源大模型和闭源大模型一直并存,各自有其独特的优势和挑战。下面,我们将从数据隐私、商业应用和社区参与三个方向,对这两种模型进行深入探讨。 一、数据隐私 开源大模型: 1. 透明度高: …

YoloV8实战:各种图绘制汇总(mAP50、mAP50-95、loss、PR_curve、F1_curve)|科研必备|绘图神器

摘要 本文的内容是告诉大家如何绘制mAP50、mAP50-95、loss、PR_curve、F1_curve等图像,方便大家写论文。 绘制mAP50、mAP50-95、loss等图。 先上效果,如下图: 首先将,训练的result.csv汇总到一个文件夹下面(这样方便寻找),要不然找起来太麻烦。如下图: 我都放到re…

The Sandbox 和 Bitkub 联手增强东南亚元宇宙中心

作为去中心化游戏虚拟世界和区块链平台的先驱,The Sandbox 正与泰国领先的区块链网络 Bitkub Blockchain Technology Co., Ltd. 展开创新合作。双方合作的目的是将Bitkub元宇宙的影响力扩展到The Sandbox,建立一个元宇宙中心,向用户承诺从 Bi…

5.28学习总结

java复习总结 hashcode()和equals() hashcode():在Object里这个方法是通过返回地址的整数值来生成哈希值。 equals():在Object里这个方法是通过比较他们的内存地址来确定两个对象是否相同。 运行效率:hashcode的时间复杂度为O(1)(因为只要计算一次哈…

搜维尔科技:【系统集成案例】三面CAVE系统案例

用户名称:成都东软学院 主要产品:工业激光投影机、光学跟踪系统、主动立体眼镜、主动式立体眼镜发生器 在4米x9米的空间内,通过三通道立体成像,对立体模型进行数字化验证,辅助unity课程设计。 立体投影大屏方案采用的…

颈源性头痛症状及表

颈源性头痛一般表现为,就是说从枕后一直颞侧,到太阳穴附近,这个是枕小的一个疼痛,还有一部分人从枕后,沿着一个弧线(如下图)的轨迹到了前额,到我们前额,这样一个疼痛&…

Aleth-NeRF: Illumination Adaptive NeRF with Concealing Field Assumption

Abstract Aleth-NeRF: 带有隐蔽场假设的照明自适应 NeRF 照明照明标准的神经辐射场(NeRF)范例采用了一种以观察者为中心的方法,将光照和材料反射的各个方面仅仅从3D 点发射纠缠在一起。这种简化的渲染方法在准确建模在不利光照条件下捕获的图像方面提出了挑战,如弱光或过度曝…

MFC 发起 HTTP Post 请求 发送MES消息

文章目录 获取Token将获取的Token写入JSON文件 将测试参数发送到http首先将测试参数写入到TestData.JSON文件rapidjson 库需要将CString 进行类型转换才能使用,将CString 转换为const char* 发送JSON 参数到http中,并且获取返回结果写入TestFinish.JSON文…

vue3 使用css实现一个弧形选中角标样式

文章目录 1. 实现效果2. 实现demo 在前端开发中,ui同学经常会设计这样的样式,用于区分选中的状态 下面抽空简单些了一下,记录下,后面直接复制用 1. 实现效果 实现一个菜单切换,右下角有个角标的样式 2. 实现demo 主要…

【Qt QML】Dialog组件

带有标准按钮和标题的弹出对话框,用于与用户进行短期交互。 这个描述指的是一个常见的用户界面元素,即一个临时弹出的窗口(或对话框),它包含一个标题,显示对话框的用途或内容描述,以及一系列标…

学习笔记——动态路由协议——OSPF(OSPF区域)

四、OSPF区域 OSPF路由器在同一个区域(Area)内网络中泛红LSA(链路状态通告)。为了确保每台路由器都拥有对网络拓扑的一致认知,LSDB需要在区域内进行同步。如果OSPF域仅有一个区域,随着网络规模越来越大,LSDB越来越庞大,OSPF路由器…

走进智慧仓储:3D可视化工厂园区革新物流新纪元

在快节奏的现代生活中,物流仓储行业扮演着至关重要的角色。随着科技的飞速发展,传统仓储模式正面临一场前所未有的变革。今天,就让我们一起看看3D可视化技术如何为物流行业带来前所未有的便利与效率。 什么是3D可视化工厂园区? 3…

flowable6springboot2 工作流从入门到精通

相关文档 https://tkjohn.github.io/flowable-userguide/ 文档手册 https://github.com/flowable/flowable-engine/releases/tag/flowable-6.8.0 flowable-ui下载地址 https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.100/bin/apache-tomcat-8.5.100.zip tomcat下载 百度网盘…

效率工作:一键为多种资产添加统一材质(小插件)

1.需求分析: 当导入一批资产,或者有同一批结构体需要添加相同材质时,单独为每个模型都添加材质费时费力,有没有什么办法,能同时为多个资产添加材质。 2.操作实现 1.在网上找到了一款插件,经过验证&#xf…

SQL2017附加从其他电脑复制过来的mdf数据后出现【只读】无法写入数据

1. 尝试给它所在的文件夹的属性中的“只读”去勾,无果。 2. 其他文章提示是文件的问题。 该错误为文件权限错误,找到该数据库的 数据库文件 和 日志文件,在安全中添加 Authenticated Users 用户的权限,并设置 “完全控制”

Idea工具的使用技巧与常见问题解决方案

一、使用技巧 1、启动微服务配置 如上图,在编辑配置选项,将对应的启动入口类加进去, 增加jvm启动参数, 比如: -Denvuat 或者 -Denvuat -Dfile.encodingUTF-8 启动配置可能不是-Denvuat,这个自己看代…

04 FreeRTOS 队列(queue)

1、队列的特性 队列可以理解为一个传送带,一个流水线。 队列可以包含若干个数据:队列中有若干项,这被称为"长度"(length) 每个数据大小固定 创建队列时就要指定长度、数据大小 数据的操作采用先进先出的方法(FIFO,First…

【Spring-01】BeanFactory和ApplicationContext

【Spring-01】BeanFactory和ApplicationContext 1. 容器接口1.1 什么是 BeanFactory1.2 BeanFactory 能做什么? 1. 容器接口 以 SpringBoot 的启动类为例: /*** BeanFactory 与 ApplicationContext的区别*/ SpringBootApplication public class Spring…

27快28了,想转行JAVA或者大数据,还来得及吗?

转行到JAVA或者大数据领域,27岁快28岁的年龄完全来得及。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给个评论222,私信22,我在后台发给你。…