全网最牛,Pytest自动化测试-pytest.mark.parametrize参数化实战(详细)

news2024/11/17 10:05:50


前言

pytest允许在多个级别启用测试参数化:

@pytest.mark.parametrize:允许在测试函数或类中定义多组参数和fixtures
pytest_generate_tests:允许定义自定义参数化方案或扩展(拓展)

参数化场景
只有测试数据和期望结果不一样,但操作步骤是一样的测试用例可以用上参数化;

参数化例子
未参数化的代码

def test_1():
assert 3 + 5 == 9


def test_2():
assert 2 + 4 == 6


def test_3():
assert 6 * 9 == 42

可以看到,三个用例都是加法然后断言某个值,重复写三个类似的用例有点冗余

利用参数化优化之后的代码

@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
print(f"测试数据{test_input},期望结果{expected}")
assert eval(test_input) == expected

执行结果

B1

可以看到,只有一条用例,但是利用参数化输入三组不同的测试数据和期望结果,最终执行的测试用例数=3,可以节省很多代码

实际Web UI自动化中的开发场景

比如是一个登录框:
你肯定需要测试账号空、密码空、账号密码都为空、账号不存在、密码错误、账号密码正确等情况

这些用例的区别就在于输入的测试数据和对应的交互结果
所以我们可以只写一条登录测试用例,然后把多组测试数据和期望结果参数化,节省很多代码量

源码分析

def parametrize(self,argnames, argvalues, indirect=False, ids=None, scope=None): 

argnames

源码解析:a comma-separated string denoting one or more argument names, or a list/tuple of argument strings.
含义:参数名字
格式:字符串"arg1,arg2,arg3"【需要用逗号分隔】
备注:源码中写了可以是参数字符串的list或者tuple,但博主实操过是不行的,不知道是不是写的有问题,大家可以看看评论下

示例

@pytest.mark.parametrize(["name", "pwd"], [("yy1", "123"), ("yy2", "123")])  
@pytest.mark.parametrize(("name", "pwd"), [("yy1", "123"), ("yy2", "123")])  
@pytest.mark.parametrize("name,pwd", [("yy1", "123"), ("yy2", "123")])

argvalues
源码解析:
The list of argvalues determines how often a test is invoked with different argument values.
If only one argname was specified argvalues is a list of values.【只有一个参数,则是值列表】
If N argnames were specified, argvalues must be a list of N-tuples, where each tuple-element specifies a value for its respective argname.【如果有多个参数,则用元组来存每一组值】

含义:参数值列表
格式:必须是列表,如:[ val1,val2,val3 ]
如果只有一个参数,里面则是值的列表如:@pytest.mark.parametrize(“username”, [“yy”, “yy2”, “yy3”])

如果有多个参数例,则需要用元组来存放值,一个元组对应一组参数的值,如:@pytest.mark.parametrize(“name,pwd”, [(“yy1”, “123”), (“yy2”, “123”), (“yy3”, “123”)])

备注:虽然源码说需要list包含tuple,但我试了下,tuple包含list,list包含list也是可以的…

ids
含义:用例的ID
格式:传一个字符串列表
作用:可以标识每一个测试用例,自定义测试数据结果的显示,为了增加可读性
强调:ids的长度需要与测试数据列表的长度一致

indirect
作用:如果设置成True,则把传进来的参数当函数执行,而不是一个参数(下一篇博文即讲解)

装饰测试类

@pytest.mark.parametrize('a, b, expect', data_1)
class TestParametrize:

    def test_parametrize_1(self, a, b, expect):
        print('\n测试函数11111 测试数据为\n{}-{}'.format(a, b))
        assert a + b == expect

    def test_parametrize_2(self, a, b, expect):
        print('\n测试函数22222 测试数据为\n{}-{}'.format(a, b))
        assert a + b == expect

执行结果

B2

重点
当装饰器 @pytest.mark.parametrize 装饰测试类时,会将数据集合传递给类的所有测试用例方法

笛卡尔积,多个参数化装饰器

# 笛卡尔积,组合数据
data_1 = [1, 2, 3]
data_2 = ['a', 'b']


@pytest.mark.parametrize('a', data_1)
@pytest.mark.parametrize('b', data_2)
def test_parametrize_1(a, b):
    print(f'笛卡尔积 测试数据为 : {a}{b}')

执行结果

B3

注意:
一个函数或一个类可以装饰多个 @pytest.mark.parametrize

这种方式,最终生成的用例数是nm,比如上面的代码就是:参数a的数据有3个,参数b的数据有2个,所以最终的用例数有32=6条
当参数化装饰器有很多个的时候,用例数都等于nnnn

参数化 ,传入字典数据

# 字典
data_1 = (
    {
        'user': 1,
        'pwd': 2
    },
    {
        'user': 3,
        'pwd': 4
    }
)


@pytest.mark.parametrize('dic', data_1)
def test_parametrize_1(dic):
    print(f'测试数据为\n{dic}')
    print(f'user:{dic["user"]},pwd{dic["pwd"]}')

没啥特别的,只是数据类型是常见的dict而已

执行结果

09parametrize.py::test_parametrize_1[dic0] PASSED                        [ 50%]测试数据为
{'user': 1, 'pwd': 2}
user:1,pwd2

09parametrize.py::test_parametrize_1[dic1] PASSED                        [100%]测试数据为
{'user': 3, 'pwd': 4}
user:3,pwd4

参数化,标记数据

# 标记参数化
@pytest.mark.parametrize("test_input,expected", [
    ("3+5", 8),
    ("2+4", 6),
    pytest.param("6 * 9", 42, marks=pytest.mark.xfail),
    pytest.param("6*6", 42, marks=pytest.mark.skip)
])
def test_mark(test_input, expected):
    assert eval(test_input) == expected

执行结果

B4

参数化,增加可读性

# 增加可读性
data_1 = [
    (1, 2, 3),
    (4, 5, 9)
]

# ids
ids = ["a:{} + b:{} = expect:{}".format(a, b, expect) for a, b, expect in data_1]


@pytest.mark.parametrize('a, b, expect', data_1, ids=ids)
class TestParametrize(object):

    def test_parametrize_1(self, a, b, expect):
        print('测试函数1测试数据为{}-{}'.format(a, b))
        assert a + b == expect

    def test_parametrize_2(self, a, b, expect):
        print('测试函数2数据为{}-{}'.format(a, b))
        assert a + b == expect

执行结果

B5

注意:
多少组数据,就要有多少个id,然后组成一个id的列表
作用:主要是为了更加清晰看到用例的含义

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

一、Python编程入门到精通

请添加图片描述

二、接口自动化项目实战

请添加图片描述

三、Web自动化项目实战

请添加图片描述

四、App自动化项目实战

请添加图片描述

五、一线大厂简历

请添加图片描述

六、测试开发DevOps体系

请添加图片描述

七、常用自动化测试工具

请添加图片描述

八、JMeter性能测试

请添加图片描述

九、总结(尾部小惊喜)

不经历风雨,怎能见彩虹;不经历磨砺,怎能拥有坚强。奋斗是通往成功的钥匙,努力是实现梦想的桥梁。不忘初心,砥砺前行,只要坚持不懈,未来必将辉煌!

只有不断超越自己的极限,才能发现无限的潜力;只有燃烧心中的梦想,才能走向辉煌的人生。让每一天都成为你奋斗的理由,成就未来的辉煌。

只要心怀梦想,坚持奋斗,即便前路崎岖,也能砥砺前行,最终成就辉煌。不忘初心,执着追求,每一步努力都是成长的殿堂,让我们勇往直前,无畏困难,创造属于自己的辉煌时刻。

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

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

相关文章

删除数据库记录错误

删除数据库记录错误:Unexpected update count received (Actual: 2, Expected: 1). All changes will be rolled back. 解决:同时删掉ID为8的记录就行了 分析:这种情况是未设置主键约束,插入了相同的记录导致的。推测应该是框架对…

Clip-Path

前言 借助clip-path,我们可以实现一些复杂的animation动画效果,我们先来简单概述一下它的特性,如MDN所描述的。 The clip-path CSS property creates a clipping region that sets what part of an element should be shown. Parts that are inside the region are shown, whi…

基于aarch64分析kernel源码 一:环境搭建

一、测试环境 功能工具操作系统ubuntu 22.04编译工具gcc-12-aarch64-linux-gnu调试工具gdb-multiarch模拟器qemu 6.2.0busyboxbusybox-1.36.1kernellinux-6.4.1编辑器vscode 二、编译器 1、查找ubuntu仓库中aarch64编译器 lqlq-virtual-machine:~/my$ apt-cache search aar…

零矩阵

暴力解法:先全部检索,定位0所在的位置, 记录到新的数组 数组的行列分别进行去重 数组中记录的行列赋值为零 如果直接修改,在行被修改之后,修改列时会因为行已经被修改产生影响 import org.junit.Test;import java.uti…

tensorboard命令行使用方法

第一步:进入虚拟环境 conda activate 虚拟环境名称 第二步: tensorboard --logdir绝对地址 第三步:在浏览器输入提供的网址

day03 重新学python——python函数

文章目录 一、python函数1.函数介绍2.函数的定义3.函数的参数4.函数的返回值5.函数的说明文档6.函数的嵌套调用7.变量的作用域8.综合案例 一、python函数 1.函数介绍 函数:即组织好的、课重复利用,用来实现特殊功能的代码段,这样可以提高代码…

生产者消费者

前言 生产者消费者模式属于一种经典的多线程协作的模式,弄清生产者消费者问题能够让我们对于多线程编程有更深刻的理解,下面,为大家分享一个生产者消费者的案例。 一、案例描述 这里以快递为例,假设有一个快递柜,用来…

蚂蚁链发布零知识证明技术架构 可满足数据“隐私保护”、“可验证”双要求

7 月 8 日,在 2023WAIC 全球区块链产业高峰论坛上,蚂蚁链宣布隐私协作平台 AntChain FAIR 进行全新架构升级,引入零知识证明(ZKP)为核心的可验证计算技术,从可信数据流转拓展到计算过程、数据属性以及身份的…

Vmware环境下的CentOS安装

CentOS7 下载安装 因为 centos 是安装在 VMware 上面的,所以需要提前安装 VMware centos 下载 网址:http://isoredirect.centos.org/centos/7/isos/x86_64/ 镜像源:http://centos.mirror.rafal.ca/7.9.2009/isos/x86_64/ 安装 centos 创建…

哪些软件分析工具需要使用到pdb符号文件?

目录 1、什么是pdb文件?pdb文件有哪些用途? 2、pdb文件的时间戳与pdb文件名称 3、常用软件分析工具有哪些? 4、使用Windbg调试器查看函数调用堆栈时需要加载pdb文件 4.1、给Windbg设置pdb文件路径 4.2、为什么要设置系统库pdb文件下载服…

深度剖析线上应用节点流量隔离技术

作者:谢文欣(风敬) 为什么要做流量隔离 源于一个 EDAS 客户遇到的棘手情况:他们线上的一个 Pod CPU 指标异常,为了进一步诊断问题,客户希望在不重建此 Pod 的情况下保留现场,但诊断期间流量还…

Element-UI 实现动态增加多个输入框并校验

文章目录 前言实现通过按钮动态增加表单并验证必填实现动态多个输入框为行内模式,其它为行外模式 前言 在做复杂的动态表单,实现业务动态变动,比如有一条需要动态添加的el-form-item中包含了多个输入框,并实现表单验证&#xff0…

非线性激活函数

目录 理论介绍 常见的激活函数 A. sigmoid函数 B. tanh C.ReLu Leaky Relu 函数 Parametric ReLU (PReLU) Exponential Linear Unit (ELU) 实验结果及分析 理论介绍 在神经网络的计算中,无非就是矩阵相乘,输入的是线性,不论输出层有…

如何修复ssh漏洞进行版本升级

目录 一、ssh低版本漏洞信息 OpenSSH GSSAPI 处理远端代码执行漏洞 OpenSSH GSSAPI认证终止信息泄露漏洞 OpenSSH X连接会话劫持漏洞 二、升级ssh版本进行修复漏洞 第一步 安装Telnet服务 第二步 重启服务 第三步 安装依赖环境 第四步 备份ssh老版本文件 第五步 导入…

【JavaEE进阶】Spring 创建与使用

Spring 创建与使用 1,Spring项目的创建 使用Maven方式来创建一个Spring项目,创建Spring项目和Servlet类似,总共分为以下3步: 创建一个普通Maven项目添加 Spring 框架⽀持(spring-context、spring-beans)添…

UE特效案例 —— 魔法翅膀

一,环境配置 创建默认地形Landscape,如给地形上材质需确定比例;添加环境主光源DirectionalLight,设置相应的强度和颜色;PostProcessVolume设置曝光,设置Min/Max Brightness为1; 与关闭Game Sett…

【二分查找】35. 搜索插入位置

35. 搜索插入位置 解题思路 使用二分查找算法当找到元素之后直接返回位置即可当没找到元素&#xff0c;将该元素插入到left位置即可 class Solution {public int searchInsert(int[] nums, int target) {// 二分查找int left 0;int right nums.length - 1;while(left < …

数组扁平化flat方法的多种实现

flat() let arr [[1],[2, 3],[4, 5, 6, [7, 8, [9, 10, [11]]]],12 ];// 参数指要提取嵌套数组的结构深度&#xff0c;默认值为 1。 // Infinity 指递归嵌套的所有层级。 let flattedArr arr.flat(Infinity); console.log(flattedArr);执行效果&#xff1a; toString() 注意…

FreeRTOS ~(六)信号量 ~ (2/3)信号量解决互斥缺陷

前情提要 FreeRTOS ~&#xff08;四&#xff09;同步互斥与通信 ~ &#xff08;2/3&#xff09;互斥的缺陷 FreeRTOS ~&#xff08;五&#xff09;队列的常规使用 ~ &#xff08;2/5&#xff09;队列解决互斥缺陷 举例子说明&#xff1a;利用信号量解决前述的"互斥的缺陷&…