迅捷小莫

本公众号日常更新自动化技术,编程知识,迅捷掌握一切测试工程师需要的技术!

12篇原创内容

公众号

Pytest

在pytest中,如何实现参数化呢?我们先来说说为什么需要参数化?

实际场景可能是下面这样:

假如你现在需要写一个登入的测试用例,需要设计几种测试用例如下:

  1. 账号密码正确。预期:登入成功

  2. 账号错误。预期:账号不存在

  3. 账号正确,密码错误。预期:账号或密码错误

  4. 账号为空 or 密码为空。预期:账号密码为空

我们通常会把方法写成这样:

user_account, password = ('admin', '123456')def test_login_success():"""登入成功:return: """usr = 'admin'psw = '123456'# 调用login接口,传入usr和psw,代码省略def test_login_usr_not_exist():"""账号不存在:return: """usr = 'admin1'psw = '123456'# 调用login接口,传入usr和psw,代码省略def test_login_psw_error():"""密码错误:return: """usr = 'admin'psw = '12345'# 调用login接口,传入usr和psw,代码省略def test_login_usr_or_psw_is_empty():"""账号或密码为空:return: """usr = ''psw = ''# 调用login接口,传入usr和psw,代码省略

看起来没什么问题,对,确实没什么问题!这是很标准的用例写法,但是我们作为自动化测试工程师,怎么能满足于此。有没有更简便的方式呢?

我们观察可以看到 ,除了省略那部分一模一样的代码,其他不一样的只是usr和psw两个数据而已,我们只需要每次去改变这两个参数的值就行了 。那么这里就需要用到我们的参数化,所以在这里,参数化的作用是什么?提高编写用例的效率!

01

pytest的参数化方式

在pytest中,我们通常有两种参数化方式:

  1. 使用@pytest.mark.parametrize装饰器

  2. 使用fixture,对没错,又是fixture

@pytest.mark.parametrize是pytest自带的装饰器之一,我们可以直接使用。而fixture也是很神奇,上篇文章介绍过,fixture是测试固件,可以用来帮助我实现类似setUp,tearDown这些函数,实际上fixture同样可以用来处理参数化。

02

使用parametrize实现参数化

@pytest.mark.parametrize可以直接装饰在任何的测试函数上面,非常的方便,我们改写一下之前的例子,如下:

import pytesttest_data = [{'usr': 'admin',  # 正常登入'psw': '123456'},{'usr': 'admin1',  # 账号不存在'psw': '123456'},{'usr': 'admin',  # 密码错误'psw': '12345'},{'usr': '',  # 账号或密码为空'psw': ''},
]@pytest.mark.parametrize('param', test_data)
def test_login(param): # 这个param需要和上面的'param'一致print(param) # 打印 if __name__ == '__main__':  # 定义主函数pytest.main()  # 调用pytest

这时候我们尝试执行一下:

可以看到,现在的测试用例变成了四条,也就是test_data的列表长度,并且这时候的param就是test_data中的每个字典!那我们想要使用字典里的数据那就非常简单了,稍微改写一下代码:

@pytest.mark.parametrize('param', test_data)
def test_login(param):usr = param.get('usr') # 获取字典中的usrpsw = param.get('psw') # 获取字典中的usrprint(f'usr: {usr} , psw: {psw}')# 调用login接口,传入usr和psw,代码省略

执行结果:

这样就取到了usr和psw两个字段,非常的简单。但是好像还是没满足我们的需求,少了测试用例的名称,这个pytest也给我们考虑到了,我们可以使用@pytest.mark.parametrize中有个ids字段,这个字段可以设置测试用例的标题,所以我们改造下代码:

test_data = [{'case': '登入成功','usr': 'admin',  # 正常登入'psw': '123456'},{'case': '账号不存在','usr': 'admin1',  # 账号不存在'psw': '123456'},{'case': '密码错误','usr': 'admin',  # 密码错误'psw': '12345'},{'case': '账号或密码为空','usr': '',  # 账号或密码为空'psw': ''},
]@pytest.mark.parametrize('param', test_data, ids=[data.get('case') for data in test_data])  # ids需要传入一个列表,我们利用列表推导式
def test_login(param):usr = param.get('usr')psw = param.get('psw')print(f'usr: {usr} , psw: {psw}')# 调用login接口,传入usr和psw,代码省略if __name__ == '__main__':  # 定义主函数pytest.main()  # 调用pytest

呆莫,执行的结果不如人意:

可以看到这时候出现了一些乱码,所以我们需要对乱码进行处理:

  1. 新建一个conftest.py文件

  2. 在里面加入下面一段代码:

def pytest_collection_modifyitems(items):"""修改用例名称中文乱码:param items::return:"""for item in items:item.name = item.name.encode('utf-8').decode('unicode_escape')item._nodeid = item.nodeid.encode('utf-8').decode('unicode_escape')

这里利用的实际上是pytest中的Hook机制,这块内容暂且先不介绍,后续会给大家介绍。总的来说,这就是个处理乱码的Hook函数。

加了之后,我们再去执行一下,发现这个时候已经没有问题了:

03

使用fixture实现参数化

那么下面我们再看一下fixture是如何实现参数化的?它为什么能实现参数化?

fixture提供了这么一个机制,fixture装饰的函数拥有一个内置的对象request,同时fixture中还有一个params参数是用来传递参数化数据的,直接上代码:

import pytest  # 导入pytesttest_data = [{'case': '登入成功','usr': 'admin',  # 正常登入'psw': '123456'},{'case': '账号不存在','usr': 'admin1',  # 账号不存在'psw': '123456'},{'case': '密码错误','usr': 'admin',  # 密码错误'psw': '12345'},{'case': '账号或密码为空','usr': '',  # 账号或密码为空'psw': ''},
]@pytest.fixture(params=test_data)  # 给params传入参数化数据
def param_data(request):return request.param  # 返回request对象中的param,这里存放的就是参数化数据def test_login(param_data): # 测试函数传入fixtureusr = param_data.get('usr')psw = param_data.get('psw')print(f'usr: {usr} , psw: {psw}')# 调用login接口,传入usr和psw,代码省略if __name__ == '__main__':  # 定义主函数pytest.main()  # 调用pytest

在上面的代码中,我们定义了一个fixture,把参数化的数据传入了params,同时给fixture设置了返回request.param。在测试函数中,我们把定义好的fixture传入即可。通过fixture我们就能拿到每次迭代的参数化数据了!

那么?fixture支不支持传入用例名称呢?当然是支持的!fixture也给我们提供了ids的参数,如下:

@pytest.fixture(params=test_data, ids=[data.get('case') for data in test_data])  # 给params传入参数化数据,ids传入case名称列表
def param_data(request):return request.param  # 返回request对象中的param,这里存放的就是参数化数据

执行结果如下:

可以看到左侧的用例标题和右侧的输出都很完美,没有问题!不过要记得conftest.py中的Hook函数同样也是需要的呢。

那么本期内容到此结束,有什么问题可以及时联系小提莫,会及时进行解答,谢谢关注!

迅捷小莫

本公众号日常更新自动化技术,编程知识,迅捷掌握一切测试工程师需要的技术!

12篇原创内容

公众号

关注我们

扫二维码

pytest系列——参数化的使用相关推荐

  1. Pytest之参数化

    VOL 154 02 2020-09 今天距2021年120天 这是ITester软件测试小栈第154次推文 点击上方蓝字"ITester软件测试小栈"关注我,每周一.三.五早上  ...

  2. pytest实战--参数化parametrize+前置fixture

    文章目录 参数化 parametrize 适用场景 一个典型的例子 前置fixture+参数化 适用场景 一个典型的例子 示例2 个人疑问? pytest既可以用来做单元测试,也可以用来做自动化接口测 ...

  3. pytest中参数化方法,并且根据执行的命令进行动态参数化

    pytest中参数化的几种方法 @pytest.mark.parametrize 元组组成的列表进行参数化,每一组元素表示一组参数化值 每个参数单独赋值 添加用例id pytest.param, 针对 ...

  4. Pytest fixture参数化params

    unittest使用ddt来实现测试用例参数化.或parameterized实现测试用例参数化,pytest测试用例里面对应的参数可以用 parametrize 实现参数化,今天我们来了解下fixtu ...

  5. pytest.5.参数化的Fixture

    From: http://www.testclass.net/pytest/parametrize_fixture/ 背景 继续上一节的测试需求,在上一节里,任何1条测试数据导致断言不通过后测试用例就 ...

  6. Pytest系列——allure(原理)之allure工具与Pytest测试框架集成

    官方介绍 1.Allure Framework是一种灵活的轻量级多语言测试报告工具,不仅可以以简洁的Web报告形式非常简洁地显示已测试的内容,也允许参与开发过程的每个人从日常测试中提取最大程度的有用信 ...

  7. pytest系列——fixture函数使用(pytest测试框架测试固件)

    前言 setup和teardown能实现在测试用例执行之前或之后做一些操作,但是这种是整个测试脚本全局生效的: 如果我们想实现某些用例执行之前进行登录,某些用例执行之前不需要进行登录,这种场景我们再使 ...

  8. pytest.ini配置文件详解【pytest系列 12】

    1.pytest中的配置文件的作用 pytest.ini pytest的主配置文件,可以改变pytest的默认行为,即pytest会读取该配置信息,然后按照指定的方式去运行 conftest.py 测 ...

  9. pytest系列——allure(三)之在测试报告中为测试用例添加附件(@allure.attach())

    前言 allure测试报告同样支持显示不同类型的附件,对测试用例.测试步骤以及fixture函数的结果加以补充. allure.attach() 或者 allure.attach.file 的作用是为 ...

  10. fixture使用详解【pytest系列 4】

    1.前言 setup和teardown可以实现用例执行前和执行后加入一些操作,但是这种操作是全局的生效的 有一些操作,我们只想要做用在部分用例上,这时可以使用fixture来自定义前置操作 2.fix ...

最新文章

  1. mysql 超时异常_java.sql.SQLException:超出锁定等待超时;尝试在MYSQL中重启事务异常...
  2. V8 —— 你需要知道的垃圾回收机制
  3. Problem B: 故障电灯(light)
  4. python 将图片转换成像素画_Canvas 实现位图转像素画
  5. python中parse是什么_Python中optparse模块使用浅析
  6. java输入正确的信息_判断用户输入的信息是否正确
  7. 华为nova4是不是鸿蒙系统,华为nova 4手机什么时候可以升级鸿蒙系统?鸿蒙系统nova4升级时间介绍...
  8. jenkins -ant-svn 自动化持续部署——web应用war包 ant build.xml配置
  9. 台式机也颤抖!ROG Strix S5AS性能强悍到底
  10. Spring Cloud与微服务学习总结(2)——Spring Cloud相较于Dubbo等RPC服务框架的优势
  11. Emberjs学习之路(一)
  12. steam linux安装目录在哪,Ubuntu 16.04 LTS 64位下安装steam游戏平台
  13. linux批量文件夹名字,linux: 批量修改文件夹及文件夹下文件的名字
  14. i春秋 - Exploit-Exercises: Nebula - level00
  15. 从日志统计到大数据分析
  16. 十行代码让你的单机“影分身”,分布式训练速度快到飞起
  17. Hadoop HDFS 基本命令
  18. PDF格式和HTML,XML格式
  19. 服务器IMM2实战介绍
  20. Android-ubuntu配置

热门文章

  1. php 交换机 密码,S5100系列交换机使用正确的用户名和密码进行SSH登录时提示错误的解决方法...
  2. 理解蓝绿发布、灰度发布和滚动发布
  3. 开源开发者 David Recordon 被任命白宫技术总监
  4. Android 动画之 View动画 和 帧动画
  5. 形容等待时间长的句子_形容等待了很久的句子
  6. html中加图片边框的,用HTML代码给图片添加边框方法
  7. 其实IPv6,并不是那么完美
  8. Vue项目--仿大麦网移动端
  9. 纯代码方式实现cesium倾斜摄影单体化和楼栋分层
  10. 浅谈车载控制器产线EOL实现方式