爆肝整理,Python自动化测试-Pytest参数化实战封装,一篇打通...

news2024/12/22 22:28:32

目录:导读

    • 前言
    • 一、Python编程入门到精通
    • 二、接口自动化项目实战
    • 三、Web自动化项目实战
    • 四、App自动化项目实战
    • 五、一线大厂简历
    • 六、测试开发DevOps体系
    • 七、常用自动化测试工具
    • 八、JMeter性能测试
    • 九、总结(尾部小惊喜)


前言

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

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

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

一般写为pytest.mark.parametrize(“argnames”, argvalues)。
其中:
argnames为参数名称,可以是单个或多个,多个写法为"argname1, argname2, …";
argvalues为参数值,类型必须为list(单个参数时可以为元组,多个参数时必须为list,所以最好统一);

例如有下接口:
请求的登陆接口信息:

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

1、单个参数

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

# 待测试函数
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 == 3

if __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 items

test_case_2.py::test_add[1] PASSED                                       [ 25%]
2

test_case_2.py::test_add[2] PASSED                                       [ 50%]
3

test_case_2.py::test_add[3] PASSED                                       [ 75%]
4

test_case_2.py::test_add[4] PASSED                                       [100%]
5

============================== 4 passed in 0.02s ==============================

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

2、多个参数

测试用例需传入多个参数时,@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).text
    res = json.loads(res)
    assert res['code'] == 1000


if __name__ == '__main__':
    pytest.main()

需要注意:
代码中data的格式,可以是列表嵌套列表,也可以是列表嵌套元组,列表中的每个列表或元组代表一组独立的请求参数。
"username, password"不能写成 “username”, “password”。

运行结果如下:

A1

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

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

A2

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).text
    res = 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'] == 1000

    def test_login_02(self, username, password):
        res = login(username, password)
        assert res['msg'] == "登录成功!"

if __name__ == '__main__':
    pytest.main(["-s"])

运行结果如下:

A3

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

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

4、参数组合

在编写测试用例的过程中,有时候需要将参数组合进行接口请求,如示例的登录接口中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 json


username = ["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).text
    res = json.loads(res)
    assert res['code'] == 1000
	
	
if __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 items

test_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中参数组合方式,依此类推。

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

5、增加测试结果可读性

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

示例:

A5

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

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

ids(推荐)
ids使用方法示例如下:

import pytest
import requests
import json


data = [("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).text
    res = json.loads(res)
    assert res['code'] == 1000
    

if __name__ == '__main__':
    pytest.main()

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

运行结果如下:

A6

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

id
使用方式示例如下:

import pytest
import requests
import json


data = [
    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).text
    res = json.loads(res)
    assert res['code'] == 1000


if __name__ == '__main__':
    pytest.main()

运行结果如下:

A7

下面是我整理的2023年最全的软件测试工程师学习知识架构体系图

一、Python编程入门到精通

请添加图片描述

二、接口自动化项目实战

请添加图片描述

三、Web自动化项目实战

请添加图片描述

四、App自动化项目实战

请添加图片描述

五、一线大厂简历

请添加图片描述

六、测试开发DevOps体系

请添加图片描述

七、常用自动化测试工具

请添加图片描述

八、JMeter性能测试

请添加图片描述

九、总结(尾部小惊喜)

奋斗是一段漫长的旅程,痛苦与磨难只是通往成功的试炼。不惧困难,坚守信念,用汗水浇灌梦想的花朵。相信自己,勇往直前,你将创造属于自己的辉煌,留下无悔的足迹!

执着的火焰燃烧内心,不屈的勇气驱散黑暗。放下畏惧,迎接挑战,奋斗的脚步不停歇。每一次努力铸就坚韧,每一次拼搏开启新篇章。勇往直前,追逐梦想。

人生的舞台,唯有奋斗才能谱写出绚丽的乐章。不要畏惧困难,要勇敢地迎接挑战。坚持努力,永不放弃,相信自己的力量,你将创造出意想不到的精彩人生!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Gradio:交互式Python数据应用程序的新前沿

一、说明 什么是Gradio以及如何使用Gradio在Python中创建DataApp或Web界面?使用 Gradio 将您的 Python 数据科学项目转换为交互式应用程序。 摄影:Elijah Merrell on Unsplash Gradio是一个Python库,允许我们快速为机器学习模型创建可定制的接…

工程英语翻译怎样做效果比较好

我们知道,高质量的工程翻译可以有效指导工程项目操作的执行,但市场上专业的工程英语翻译人才严重不足。那么,工程英语翻译难吗,怎样翻译工程英语比较好? 业内人士指出, 工程翻译具有用词专业、涉及领域广、…

Python(八十一)字符串的常用操作——字符串判断的相关方法

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

Python3 安装、环境变量配置、PyCharm新建Python项目

一、安装包下载 Pyhton官网下载>>最新稳定版的安装包: 找到合适的版本进行下载: 如果下载较慢,此处提供一个3.10.11的稳定版本的安装包: 链接:https://pan.baidu.com/s/16GnWjkGFuSfWfaI9UVX8qA?pwd4u5o 提取…

案例13 Spring MVC参数传递案例

基于Spring MVC实现HttpServletRequest、基本数据类型、Java Bean、数组、List、Map、JSON方式的参数传递。 1. 创建项目 选择Maven快速构建web项目&#xff0c;项目名称为case13-springmvc02。 2. 配置Maven依赖 <?xml version"1.0" encoding"UTF-8&quo…

【JavaScript】怎么测试方法的兼容性

利用网站测试方法的兼容性 打开网站&#xff1a;https://caniuse.com在里面输入要检测的方法&#xff0c;红色代表不支持&#xff0c;绿色代码支持。

Linux:Shell编程之正则表达式

目录 绪论 1、正则表达式 1.1 通配符 1.2 正则表达式分类 1.3 基本正则 1.4 正则表达式中表示次数的表达式 1.5 位置锚定 1.5.1 词首锚定和词尾锚定 1.6 分组&#xff08;&#xff09; 1.7 逻辑或 1.8 扩展正则 绪论 正则表达式&#xff1a;有一类特殊字符以及文本…

10-1_Qt 5.9 C++开发指南_Data Visualization实现数据三维显示

Data Visualization 是 Qt 提供的用于数据三维显示的模块。在 Qt 5.7 以前只有商业版才有此模块&#xff0c;而从Qt5.7 开始此模块在社区版本里也可以免费使用了。Data Visualization 用于数据的三维显示&#xff0c;包括三维柱状图、三维空间散点、三维曲面等。Data Visualiza…

【教程】初识云函数,实现无需服务器的项目上云!

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 你是否也在忧愁&#xff0c;想把自己的项目放在云上跑&#xff0c;但又不想花大价钱购买云服务器&#xff1f; 云函数介绍 云函数(Serverless Cloud Function&#xff0c;SCF)的简单理解就是&#xff1a;可以部署…

第四十八周周报

学习目标&#xff1a; 修改ViTGAN 学习内容&#xff1a; 位置编码和多尺度 学习时间&#xff1a; 8.5-8。12 学习产出&#xff1a; 这两周主要工作在修改ViTGAN的结构和代码&#xff0c;将相对位置编码加入ViTGAN并将生成器变为多尺度&#xff0c;由于匹配维度很困难&am…

国产航顺HK32F030M: 内部参考电压

HK32F030MF4P6 用户手册 内部参考电压 adc.c #include "bsp_adc.h"/*** brief ADC GPIO 初始化* param 无* retval 无*/ static void ADCx_GPIO_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;// 打开 ADC IO端口时钟ADC_GPIO_AHBxClock_FUN ( ADC_GPIO_C…

无涯教程-Perl - msgctl函数

描述 该函数使用参数ID,CMD和ARG调用系统函数msgctrl()。您可能需要包括IPC::SysV包以获得正确的常量。 语法 以下是此函数的简单语法- msgctl ID, CMD, ARG返回值 该函数返回0,但如果系统函数成功返回0和1,则返回true。 Perl 中的 msgctl函数 - 无涯教程网无涯教程网提供…

TCP协议的报头格式和滑动窗口

文章目录 TCP报头格式端口号序号和确认序号确认应答&#xff08;ACK&#xff09;机制超时重传机制 首部长度窗口大小报文类型URGACKSYNPSHFINRST 滑动窗口滑动窗口的大小怎么设定怎么变化滑动窗口变化问题 TCP报头格式 端口号 两个端口号比较好理解&#xff0c;通过端口号来找…

3.UE基本操作及数字人工程模块组成(UE数字人系统教程)

1.Fay-UE5数字人工程导入 2.UE数字人语音交互 3.UE基本操作及数字人工程模块组成&#xff08;UE数字人系统教程&#xff09; 一、ue5基本操作 1、项目文件管理 2、关卡素材编辑 在关卡上&#xff1a;w、s、a、d移动&#xff0c;鼠标右键拖动换视角。 二、数字人工程模…

Downie 4 for Mac

Downie是一款Mac平台上非常实用的视频下载工具。它支持下载各种视频网站上的视频&#xff0c;并且具有快速、稳定、易于使用的特点。 Downie具有快速、稳定的下载速度&#xff0c;可以帮助用户轻松地下载高清视频和音频文件。 该软件还提供了简洁、易于使用的界面&#xff0c;…

Java并发编程(三)线程同步 上[synchronized/volatile]

概念 当使用多个线程来访问同一个数据时,将会导致数据不准确,相互之间产生冲突,非常容易出现线程安全问题,比如多个线程都在操作同一数据,都打算修改商品库存,这样就会导致数据不一致的问题。 所以我们通过线程同步机制来保证线程安全,加入同步锁以避免在该线程没有完成操作之前…

C++文件类(整理自C语言中文网-全)

C文件类&#xff08;文件流类&#xff09;及用法详解 《C输入输出流》一章中讲过&#xff0c;重定向后的 cin 和 cout 可分别用于读取文件中的数据和向文件中写入数据。除此之外&#xff0c;C 标准库中还专门提供了 3 个类用于实现文件操作&#xff0c;它们统称为文件流类&…

2.0 Maven基础

1. Maven概述 Maven概念 Apache Maven是一个软件项目管理工具&#xff0c;将项目开发和管理过程抽象程一个项目对象模型&#xff08;POM&#xff0c;Project Object Model&#xff09;。 Maven作用 项目构建 提供标准的、跨平台的自动化项目构建方式。 依赖管理 方便快捷…

【Java】数据交换 Json 和 异步请求 Ajax

&#x1f384;欢迎来到边境矢梦的csdn博文&#xff0c;本文主要讲解Java 中 数据交换和异步请求 Json&Ajax 的相关知识&#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#…

【枚举】CF1660 D

Problem - 1660D - Codeforces 题意&#xff1a; 思路&#xff1a; 思路巨简单&#xff0c;代码也wa了很多发才过&#xff0c;都是因为细节.... 很显然&#xff0c;要根据0分段处理 对于每一段&#xff0c;枚举去掉左边段还是右边段&#xff0c;左边段是 l 到第一个负数&am…