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

使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 18--测试框架Pytest基础 2--插件和参数化

测试学习记录,仅供参考!

Pytest 框架

七、pytest 丰富的插件系统

可以去安装外部的插件,去使用 pytest 来执行插件;这就是为什么选择使用 pytest 框架的原因,因为 pytest 里面有丰富的插件系统,而 unittest 是没有这些插件的;所以 pytest 要比 unittest 测试框架更加灵活;

例如:

当测试用例很多的时候,可以使用并发执行,可以使用多进程/多线程去执行测试用例,提高测试效率;

测试用例失败重跑插件;在执行测试用例时,由于网络波动、硬件设备等不确定的因素,导致执行测试用例失败,但并不是测试结果测试失败的情况下,可以用到重试运行失败用例重跑的插件;

执行测试用例顺序的插件、生成测试报告的插件、数据参数化等等;

第一个、并发执行(多进程/多线程)

pytest-xdist 提供一个 -n 参数选项设置多进程/线程数量,去设置多少个线程去执行测试用例;使得测试用例可以在多个进程或线程中并发执行,提供测试效率;

安装插件

pip install pytest-xdist

在 main 函数中设置进程数;

命名行
pytest test_plug_in.py -n 3

配置文件 pytest.ini 中设置,然后再运行 run.py 主方法函数文件;
[pytest]
addopts = -vs -n 3testpaths = ./testcase
; testpaths = ./otherpython_files = test_*.pypython_classes = Test*python_functions = test_*
第二个、测试用例失败重跑

安装插件

pip install pytest-rerunfailures

模拟场景

定义一个 class TestReRunFailed: 测试类 ;

定义一个 def test_rerun_fail_case(self): 方法;

模拟偶发性失败、或是环境因素导致的测试失败;

写一个随机数随机执行,再断言随机选择“随机真值、假值”,然后去执行;

怎么使用失败重跑插件
对单个测试用例设置失败重跑次数

去关注平时跑的测试用例,哪一个用例波动比较大的,可以在那一个测试用例的前面添加 @pytest.mark.flaky() 装饰器,去设置重跑次数,里面需要用到两个参数,第一个 reruns=3 参数是当用例失败时会重跑次数(指定失败时重跑的次数),第二个 reruns_delay=2 参数是指定重试之间的延迟时间;这是对单个测试用例去设置重跑的次数;,根据平时跑的一个结果,去判定哪条测试用例报错比较多,就在那条测试用例加上失败重跑调试;

代码演示:

import pytestclass TestReRunFailed:@pytest.mark.flaky(reruns=3, reruns_delay=2)def test_rerun_fail_case(self):import randomassert random.choice([True, False])def test_rerun_fail_case02(self):import randomassert random.choice([True, False])if __name__ == '__main__':pytest.main()# pytest.main(['--reruns=3'])    
对所有测试用例设置失败重跑次数

在 pytest.ini 配置文件中去设置测试用例失败重跑参数,为所有的测试用例默认加上失败重跑的次数;

[pytest]
addopts = -vs --reruns 3testpaths = ./testcasepython_files = test_*.pypython_classes = Test*python_functions = test_*
第三个、测试用例执行顺序

因为在默认情况下,pytest 会以特定的顺序运行测试用例;可以使用 pytest-ordering 插件去自定义设置测试用例的执行顺序;

通常是按照测试文件中定义的顺序去执行,但是有的时候,测试用例的执行顺序对于特定的场景可能很重要,此时就需要更加精细的去控制测试用例的执行顺序;比如要去删除某一个用户,这种情况首先得先去跑执行新增创建用户的用例,只有新增完成之后,才能有数据去调用删除接口;

安装插件,通过插件去改变测试用例的执行顺序;

pip install pytest-ordering

第一种写法

通过 pytest 装饰器 @pytest.mark.run(order=4) 调用插件里面的 run 方法来设置执行顺序;

import pytestclass TestOrdering:@pytest.mark.run(order=4)def test_ordering_case_01(self):print('第一个测试用例')@pytest.mark.run(order=5)def test_ordering_case_02(self):print('第二个测试用例')@pytest.mark.run(order=1)def test_ordering_case_03(self):print('第三个测试用例')@pytest.mark.run(order=2)def test_ordering_case_04(self):print('第四个测试用例')@pytest.mark.run(order=3)def test_ordering_case_05(self):print('第五个测试用例')if __name__ == '__main__':pytest.main()

注意:当编号相同时,就根据文件设置的编码去执行了;

第二种写法、通过自定义方式
import pytestclass TestOrdering:@pytest.mark.lastdef test_ordering_case_01(self):print('第一个测试用例')@pytest.mark.firstdef test_ordering_case_02(self):print('第二个测试用例')@pytest.mark.seconddef test_ordering_case_03(self):print('第三个测试用例')if __name__ == '__main__':pytest.main()

运行后若发现警告信息(大致意思是“pytest 识别到了未注册的自定义标记”,如果使用的自定义标记不是 pytest 中自带的,而是个人自定义的时候就会出现警告信息),可以通过在 pytest.ini 配置文件中使用 markers 注册自定义标记来消除警告信息;

[pytest]
addopts = -vs --reruns 3testpaths = ./testcasepython_files = test_*.pypython_classes = Test*python_functions = test_*markers =lastfirstsecond

第四个、测试报告 allure-pytest

后续介绍。。。

八、参数化处理

在 pytest 中,参数化处理是最重要的部分之一,在实际工作场景中会经常用到,测试某一个功能时,需要传参数,才能去校验准确性;参数化是一种测试用例复用的方法,允许在一个测试函数上运行多组输入数据,以覆盖不同的测试场景,参数化使用 @pytest.mark.parametrize 装饰器来实现;

1、参数化的基本用法

使用 @pytest.mark.parametrize 装饰器,通过装饰器将参数传递给测试函数;

指定参数名和参数值;

在测试函数的参数中接收参数值,用于运行多次测试;

语法:@pytest.mark.parametrize("params1,params2,params3...",params_value)

params:参数值,可接收多个;

params_value:任何可迭代的对象,例如“列表、集合、字典等”

2、代码实现

参数化时会把“可迭代对象”里面的数据传递给“可接收参数”;

例如 可迭代对象 列表中 ['python', 'java', 'C#'] 有三组数据,参数化时会把 这三组数据 传递给 可接收参数 params;然后在测试函数中接收参数 def test_params_01(self, params): 在测试函数里面去接收参数化传递过来的值,这两个值(params)要一样,不能变,就是 @pytest.mark.parametrize 装饰器中的第一个参数 params 要和测试函数中接收的参数 params 一致;

接收单个参数
import pytestclass TestParams:@pytest.mark.parametrize("params", ['python', 'java', 'C#'])def test_params_01(self, params):print(params)

运行 run.py 主函数文件,查看 test_params_01 测试方法能不能接收到 @pytest.mark.parametrize 装饰器参数化传递的参数;

可以看到 test_params_01 这一个测试用例成功执行了三次;

接收多个参数

接收多个参数时,注意相互对应,最好数据个数和接收参数个数相同;

可迭代对象:列表
import pytestclass TestParams:@pytest.mark.parametrize("username,password", [("test01", "qwe123"), ("test02", "qwe456"), ("test03", "qwe789")])def test_login_case(self, username, password):print(f"用户名:{username},密码:{password}")

可迭代对象:集合
import pytestclass TestParams:@pytest.mark.parametrize("params", ['python', 'java', 'C#'])def test_params_01(self, params):print(params)@pytest.mark.parametrize("username,password", [("test01", "qwe123"), ("test02", "qwe456"), ("test03", "qwe789")])def test_login_case(self, username, password):print(f"用户名:{username},密码:{password}")@pytest.mark.parametrize("usernames,passwords", {("test001", "qwe0123"), ("test002", "qwe0456"), ("test003", "qwe0789")})def test_login_case_02(self, usernames, passwords):print(f"用户名:{usernames},密码:{passwords}")

可迭代对象:字典

字典的迭代对象是只迭代 key 值,所以使用一个参数去接收;一般很少使用这种场景;

import pytestclass TestParams:@pytest.mark.parametrize("params", ['python', 'java', 'C#'])def test_params_01(self, params):print(params)@pytest.mark.parametrize("username,password", [("test01", "qwe123"), ("test02", "qwe456"), ("test03", "qwe789")])def test_login_case(self, username, password):print(f"用户名:{username},密码:{password}")@pytest.mark.parametrize("usernames,passwords,address",{("test001", "qwe0123", "BJ"), ("test002", "qwe0456", "SH"), ("test003", "qwe0789", "SZ")})def test_login_case_02(self, usernames, passwords, address):print(f"用户名:{usernames},密码:{passwords},地址:{address}")@pytest.mark.parametrize("user_name", {"test0001": "qwe00123", "test0002": "qwe00456"})def test_login_case_03(self, user_name):print(f"用户名:{user_name}")

后续把参数化中的参数改造成可读取文件中的数据(例如 yaml 文件、Excel 文件等等)

未完待续。。。

http://www.dtcms.com/a/495236.html

相关文章:

  • 玩具 网站模板成立一个网站
  • 阿里网站注册阿里云网站怎么建设
  • 【排查实录】Web 页面能打开,服务器能通接口,客户端却访问失败?原因全在这!
  • 【Linux】系统性能排查:解决卡顿问题
  • 建网站要注意的细节建免费的网站
  • 手机网站建设收费网站建设 合肥
  • Qwen3-0.6模型开关思考模式测试
  • FT62FC3X 8位MCU单片机选型表,详细解析FT62FC31A/32A/33A/35A/3FA
  • 鸿蒙NEXT Sensor Service Kit开发指南:解锁传感器数据的无限潜能
  • 开源项目:FlyCut Caption智能视频字幕裁剪工具
  • Fedora 16上源码建立pydev + eclipse的OpenStack开发环境笔记草稿
  • 便携式榨汁机方案开发,榨汁机果汁机MCU控制方案设计
  • 杭州如何做百度的网站网页是什么
  • 【软考备考】软件架构设计需要考虑系统性能 如何使用缓存提高系统性能知识点七
  • 南京做网站dmooo学校自己做的网站需要买服务器吗
  • 鸿蒙实现可以上下左右滑动的表格-摆脱大量ListScroller
  • 笔试强训:Week -2
  • webpack - 单独打包指定JS文件(因为不确定打出的前端包所访问的后端IP,需要对项目中IP配置文件单独拿出来,方便运维部署的时候对IP做修改)
  • 有的网站打开的是html结尾的路径有的不是wordpress放在二级目录
  • 展示型企业网站设计方案2016年做网站能赚钱
  • 【论文精读】RD-Agent-Quant:基于多智能体框架的量化因子与模型研发自动化系统
  • 网站开发大概价格建设电子商务网站流程
  • Python 练习脚本(从基础到高级150个练习)
  • GDDR6总结(1)-背景及优劣
  • Redis 中文学习手册
  • 网站改版 程序变了 原来的文章内容链接地址 打不开怎么办以百度云做网站空间
  • iOS 混淆工具链实战,多工具组合完成 IPA 混淆与加固(iOS混淆|IPA加固|无源码混淆|App 防反编译)
  • 莞城做网站wordpress 插件数据
  • YouTube 视频评论,并插入 MySQL
  • mac idea 点击打开项目卡死