收下吧,学习一周就成功拿下15koffer的接口自动化测试框架教程pytest-参数化

本文主要是介绍收下吧,学习一周就成功拿下15koffer的接口自动化测试框架教程pytest-参数化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

么是参数化,通俗点理解就是,定义一个测试类或测试函数,可以传入不同测试用例对应的参数,从而执行多个测试用例。

例如对登录接口进行测试,假设有3条用例:正确账号正确密码登录、正确账号错误密码登录、错误账号正确密码登录,那么我们只需要定义一个登陆测试函数test_login(),然后使用这3条用例对应的参数去调用test_login()即可。

在unittest中可以使用ddt进行参数化,而pytest中也提供非常方便的参数化方式,即使用装饰器@pytest.mark.parametrize()

一般写为pytest.mark.parametrize("argnames", argvalues),其中:

  1. argnames为参数名称,可以是单个或多个,多个写法为"argname1, argname2, ......"
  2. argvalues为参数值,类型必须为list(单个参数时可以为元组,多个参数时必须为list,所以最好统一)

当然pytest.mark.parametrize()不止这两个参数,感兴趣的可以去查看源代码,后面我们还会讲到其中的参数ids

示例中所请求的登陆接口信息为:

  1. 接口url:http://127.0.0.1:5000/login
  2. 请求方式:post
  3. 请求参数:
  4. 响应信息:

单个参数

只需要传入一个参数时,示例如下:

# 待测试函数
def sum(a):return a+1# 单个参数
data = [1, 2, 3, 4]
@pytest.mark.parametrize("item", data)
def test_add(item):actual = sum(item)print("\n{}".format(actual))# assert actual == 3if __name__ == '__main__':pytest.main()

注意,@pytest.mark.parametrize()中的第一个参数,必须以字符串的形式来标识测试函数的入参,如上述示例中,定义的测试函数test_login()中传入的参数名为item,那么@pytest.mark.parametrize()的第一个参数则为"item"

运行结果如下:

rootdir: E:\blog\python接口自动化\apiAutoTest, configfile: pytest.ini
plugins: html-2.1.1, metadata-1.10.0, ordering-0.6, rerunfailures-9.1.1
collecting ... collected 4 itemstest_case_2.py::test_add[1] PASSED                                       [ 25%]
2test_case_2.py::test_add[2] PASSED                                       [ 50%]
3test_case_2.py::test_add[3] PASSED                                       [ 75%]
4test_case_2.py::test_add[4] PASSED                                       [100%]
5============================== 4 passed in 0.02s ==============================

从结果我们可以看到,测试函数分别传入了data中的参数,总共执行了5次。

多个参数

测试用例需传入多个参数时,@pytest.mark.parametrize()的第一个参数同样是字符串, 对应用例的多个参数用逗号分隔。

示例如下:

import pytest
import requests
import json# 列表嵌套元组
data = [("lilei", "123456"), ("hanmeimei", "888888")]
# 列表嵌套列表
# data = [["lilei", "123456"], ["hanmeimei", "888888"]]@pytest.mark.parametrize("username, password", data)
def test_login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)assert res['code'] == 1000if __name__ == '__main__':pytest.main()

这里需要注意:

  1. 代码中data的格式,可以是列表嵌套列表,也可以是列表嵌套元组,列表中的每个列表或元组代表一组独立的请求参数。
  2. "username, password"不能写成 "username", "password"。

运行结果如下:

从结果中我们还可以看到每次执行传入的参数,如下划线所示部分。

这里所举示例是2个参数,传入3个或更多参数时,写法也同样如此,一定要注意它们之间一一对应的关系,如下图:

对测试类参数化

上面所举示例都是对测试函数进行参数化,那么对测试类怎么进行参数化呢?

其实,对测试类的参数化,就是对测试类中的测试方法进行参数化。@pytest.mark.parametrize()中标识的参数个数,必须与类中的测试方法的参数一致。示例如下:

# 将登陆接口请求单独进行了封装,仅仅只是为了方便下面的示例
def login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)return res# 测试类参数化
data = [("lilei", "123456"), ("hanmeimei", "888888")
]
@pytest.mark.parametrize("username, password", data)
class TestLogin:def test_login_01(self, username, password):res = login(username, password)assert res['code'] == 1000def test_login_02(self, username, password):res = login(username, password)assert res['msg'] == "登录成功!"if __name__ == '__main__':pytest.main(["-s"])

运行结果如下:

从结果中可以看出来,总共执行了4次,测试类中的每个测试方法都执行了2次,即每个测试方法都将data中的每一组参数都执行了一次。

注意,这里还是要强调参数对应的关系,即@pytest.mark.parametrize()中的第一个参数,需要与测试类下面的测试方法的参数一一对应。

参数组合

在编写测试用例的过程中,有时候需要将参数组合进行接口请求,如示例的登录接口中username有 lilei、hanmeimei,password有 123456、888888,进行组合的话有下列四种情况:

{"username": "lilei", "password": "123456"}
{"username": "lilei", "password": "888888"}
{"username": "hanmeimei", "password": "123456"}
{"username": "hanmeimei", "password": "888888"}

@pytest.mark.parametrize()也提供了这样的参数组合功能,编写格式示例如下:

import pytest
import requests
import jsonusername = ["lilei", "hanmeimei"]
password = ["123456", "888888"]@pytest.mark.parametrize("password", password)
@pytest.mark.parametrize("username", username)
def test_login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)assert res['code'] == 1000if __name__ == '__main__':pytest.main()

运行结果如下:

rootdir: E:\blog\python接口自动化\apiAutoTest, configfile: pytest.ini
plugins: html-2.1.1, metadata-1.10.0, ordering-0.6, rerunfailures-9.1.1
collecting ... collected 4 itemstest_case_5.py::test_login[lilei-123456] PASSED                          [ 25%]
test_case_5.py::test_login[lilei-888888] FAILED                          [ 50%]
test_case_5.py::test_login[hanmeimei-123456] FAILED                      [ 75%]
test_case_5.py::test_login[hanmeimei-888888] PASSED                      [100%]
=========================== short test summary info ===========================
FAILED test_case_5.py::test_login[lilei-888888] - assert 1001 == 1000
FAILED test_case_5.py::test_login[hanmeimei-123456] - assert 1001 == 1000
========================= 2 failed, 2 passed in 0.18s =========================

从结果可以看出来,2个username、2个password 有4中组合方式,总执行了4次。如果是3个username、2个password,那么就有6中参数组合方式,依此类推。

注意,以上这些示例中的测试用例仅仅只是用于举例,实际项目中的登录接口测试脚本与测试数据会不一样。

增加测试结果可读性

从示例的运行结果中我们可以看到,为了区分参数化的运行结果,在结果中都会显示由参数组合而成的执行用例名称,很方便就能看出来执行了哪些参数组合的用例,如下示例:

但这只是简单的展示,如果参数多且复杂的话,仅仅这样展示是不够清晰的,需要添加一些说明才能一目了然。

因此,在@pytest.mark.parametrize()中有两种方式来自定义上图中划线部分的显示结果,即使用@pytest.mark.parametrize()提供的参数 ids 自定义,或者使用pytest.param()中的参数id自定义。

ids(推荐)

ids使用方法示例如下:

import pytest
import requests
import jsondata = [("lilei", "123456"), ("hanmeimei", "888888")]
ids = ["username:{}-password:{}".format(username, password) for username, password in data]
@pytest.mark.parametrize("username, password", data, ids=ids)
def test_login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)assert res['code'] == 1000if __name__ == '__main__':pytest.main()

从编写方式可以看出来,ids就是一个list,且它的长度与参数组合的分组数量一致。

运行结果如下:

比较上面个执行结果,我们能看出ids自定义执行结果与默认执行结果展示的区别。使用过程中,需要根据实际情况来自定义。

id

使用方式示例如下:

import pytest
import requests
import jsondata = [pytest.param("lilei", "123456", id="correct username and correct password"),pytest.param("lilei", "111111", id="correct user name and wrong password")
]@pytest.mark.parametrize("username, password", data)
def test_login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)assert res['code'] == 1000if __name__ == '__main__':pytest.main()

运行结果如下:

从个人实际使用体验来说,感觉id相对于ids,自定义的扩展性相当较小,而且我尝试着在id中使用中文进行定义,控制台显示的不是中文,而是编码后的结果。所以推荐使用ids。当然也可能是它的作用我没理解透彻。

 自动化测试相关教程推荐:

2023最新自动化测试自学教程新手小白26天入门最详细教程,目前已有300多人通过学习这套教程入职大厂!!_哔哩哔哩_bilibili

2023最新合集Python自动化测试开发框架【全栈/实战/教程】合集精华,学完年薪40W+_哔哩哔哩_bilibili

测试开发相关教程推荐

2023全网最牛,字节测试开发大佬现场教学,从零开始教你成为年薪百万的测试开发工程师_哔哩哔哩_bilibili

postman/jmeter/fiddler测试工具类教程推荐

讲的最详细JMeter接口测试/接口自动化测试项目实战合集教程,学jmeter接口测试一套教程就够了!!_哔哩哔哩_bilibili

2023自学fiddler抓包,请一定要看完【如何1天学会fiddler抓包】的全网最详细视频教程!!_哔哩哔哩_bilibili

2023全网封神,B站讲的最详细的Postman接口测试实战教学,小白都能学会_哔哩哔哩_bilibili

  总结:

 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

如果对你有帮助的话,点个赞收个藏,给作者一个鼓励。也方便你下次能够快速查找。

如有不懂还要咨询下方小卡片,博主也希望和志同道合的测试人员一起学习进步

在适当的年龄,选择适当的岗位,尽量去发挥好自己的优势。

我的自动化测试开发之路,一路走来都离不每个阶段的计划,因为自己喜欢规划和总结,

测试开发视频教程、学习笔记领取传送门!!

这篇关于收下吧,学习一周就成功拿下15koffer的接口自动化测试框架教程pytest-参数化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/463847

相关文章

Nginx设置连接超时并进行测试的方法步骤

《Nginx设置连接超时并进行测试的方法步骤》在高并发场景下,如果客户端与服务器的连接长时间未响应,会占用大量的系统资源,影响其他正常请求的处理效率,为了解决这个问题,可以通过设置Nginx的连接... 目录设置连接超时目的操作步骤测试连接超时测试方法:总结:设置连接超时目的设置客户端与服务器之间的连接

Ubuntu固定虚拟机ip地址的方法教程

《Ubuntu固定虚拟机ip地址的方法教程》本文详细介绍了如何在Ubuntu虚拟机中固定IP地址,包括检查和编辑`/etc/apt/sources.list`文件、更新网络配置文件以及使用Networ... 1、由于虚拟机网络是桥接,所以ip地址会不停地变化,接下来我们就讲述ip如何固定 2、如果apt安

PyCharm 接入 DeepSeek最新完整教程

《PyCharm接入DeepSeek最新完整教程》文章介绍了DeepSeek-V3模型的性能提升以及如何在PyCharm中接入和使用DeepSeek进行代码开发,本文通过图文并茂的形式给大家介绍的... 目录DeepSeek-V3效果演示创建API Key在PyCharm中下载Continue插件配置Con

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

Spring Boot整合log4j2日志配置的详细教程

《SpringBoot整合log4j2日志配置的详细教程》:本文主要介绍SpringBoot项目中整合Log4j2日志框架的步骤和配置,包括常用日志框架的比较、配置参数介绍、Log4j2配置详解... 目录前言一、常用日志框架二、配置参数介绍1. 日志级别2. 输出形式3. 日志格式3.1 PatternL

MyBatis-Flex BaseMapper的接口基本用法小结

《MyBatis-FlexBaseMapper的接口基本用法小结》本文主要介绍了MyBatis-FlexBaseMapper的接口基本用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具... 目录MyBATis-Flex简单介绍特性基础方法INSERT① insert② insertSelec

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

Idea实现接口的方法上无法添加@Override注解的解决方案

《Idea实现接口的方法上无法添加@Override注解的解决方案》文章介绍了在IDEA中实现接口方法时无法添加@Override注解的问题及其解决方法,主要步骤包括更改项目结构中的Languagel... 目录Idea实现接China编程口的方法上无法添加@javascriptOverride注解错误原因解决方