Pytest参数化-下篇

news2024/11/29 1:30:45

😎😎原文出自:测个der,博主的公众号,格式美观一些。

关于参数化的其他案例

数据嵌套及多参数传参

import pytest


pwd_datas = [["QINGAN",{"user":"SHIER","pwd":"123456"}],["SHIER",{"pwd":"654321","user":"QINGAN"}]]

class Test_severity:

    @pytest.mark.parametrize("user,datas",pwd_datas)
    def test_LOGIN(self,user,datas):
        print(user)
        print(datas)
"""
test_browser.py::Test_severity::test_LOGIN[QINGAN-datas0] QINGAN
{'user': 'SHIER', 'pwd': '123456'}
PASSED
test_browser.py::Test_severity::test_LOGIN[SHIER-datas1] SHIER
{'pwd': '654321', 'user': 'QINGAN'}
PASSED
"""

在后续的实战中 ,此处是最为常用的部分,不论是两个参数还是三个四个参数,都可以采用这样的方式。比如登录接口要做数据处理的操作的时候,就可以这样写,账号密码,以及备注,接口地址等,都可以直接用数据组合的方式集成到测试用例里面来。

示例

import pytest

pwd_datas = [
        ["QINGAN", 'login', {"user": "SHIER", "pwd": "123456"}],
        ["SHIER", 'login1', {"pwd": "654321", "user": "QINGAN"}]
    ]

class Test_severity:

    @pytest.mark.parametrize("user,text,datas", pwd_datas)
    def test_LOGIN(self, user, text,datas):
        print(user)
        print(datas)
        print(text)
"""
test_browser.py::Test_severity::test_LOGIN[QINGAN-login-datas0] QINGAN
{'user': 'SHIER', 'pwd': '123456'}
login
PASSED
test_browser.py::Test_severity::test_LOGIN[SHIER-login1-datas1] SHIER
{'pwd': '654321', 'user': 'QINGAN'}
login1
PASSED
"""

此处具体体现在这可能看着不是很明显,如果有一定的底子,此处还是可以看出用意的。可以将user看做账号,text看做备注信息。其他的自然就是账号密码了。可以参照后续的测试报告,可以更直观的看到测试数据的展示。

HOOK自定义参数化

自定义传参

此处都是重写并嵌入自己写的Pytest的一些方法。pytest_generate_tests方法。先看看官网的写法:

"""conftest.py"""
def pytest_addoption(parser):
    parser.addoption("--all", action="store_true", help="run all combinations")

def pytest_generate_tests(metafunc):
    if "param1" in metafunc.fixturenames:
        if metafunc.config.getoption("all"):
            end = 5
        else:
            end = 2
        metafunc.parametrize("param1", range(end))
"""test_a.py"""
def test_compute(param1):
    assert param1 < 4
$ pytest -q --all
....F                                                                [100%]
================================= FAILURES =================================
_____________________________ test_compute[4] ______________________________

param1 = 4

    def test_compute(param1):
>       assert param1 < 4
E       assert 4 < 4

test_compute.py:4: AssertionError
========================= short test summary info ==========================
FAILED test_compute.py::test_compute[4] - assert 4 < 4
1 failed, 4 passed in 0.12s

没看懂是吧。 首先需要说明的一点就是:命令行执行确实可以。但是写入到pytest配置文件就不行了。原因是你的conftest.py文件不是全局文件。 解决方案:将conftest.py挪动至你的配置文件同级目录即可。记得在addopts 参数处加上--all

解析

"""conftest.py"""
def pytest_addoption(parser):
    parser.addoption("--stringinput", action="store",help="run all combinations")

def pytest_generate_tests(metafunc):
    if "stringinput" in metafunc.fixturenames:
        metafunc.parametrize("stringinput", metafunc.config.getoption("stringinput"))
"""test_a.py"""
def test_compute(stringinput):
    print("第", stringinput,"个清安")

如果你是命令行运行,记得将配置文件的addopts = --stringinput去除,反之加上。 pytest_addoption类似于注册功能。注册一个命令参数。action类似于标记。还有一个 default 参数,help帮助提示。 metafunc.parametrize类似于返回值,metafunc.config.getoption("stringinput")也就是那个值了。括号中的字符串stringinput,也就相当于引用了,可以理解为变量。便于另一端的test使用

关于action参数,了解一下:

1. 'store'- 这只是存储参数的值。这是默认操作。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
2. 'store_const'- 这存储由 const 关键字参数指定的值。该'store_const'操作最常与指定某种标志的可选参数一起使用。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
3. 'store_true'和'store_false'- 这些是 'store_const'用于分别存储值 True 和的特殊情况 False 。此外,它们分别创建 False 和 的默认值 True。例如:
>>> parser = argparse.ArgumentParser()
>>>parser.add_argument('--foo', action='store_true')
>>>parser.add_argument('--bar', action='store_false')
4. 'append'- 这存储了一个列表,并将每个参数值附加到列表中。这对于允许多次指定选项很有用。示例用法:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
5. 'append_const'- 这存储了一个列表,并将 const 关键字参数指定的值附加到列表中(请注意,const 关键字参数默认为 None)。'append_const'当多个
参数需要将常量存储到同一个列表时,该操作通常很有用。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int
6. 'count'- 这会计算关键字参数出现的次数。例如,这对于提高详细程度很有用:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--verbose', '-v', action='count', default=0)

钩子函数本就不常用,因为pytest本身提供的方法已经可以满足我们绝大部分的需求了,所以我们目前只需要了解到此处的部分用法即可。 此外,上述例子中我们可以通过控制台或者配置文件传递多个参数:--stringinput=1 --stringinput=2

示例-action = append

"""conftest.py"""
def pytest_addoption(parser):
    parser.addoption("--stringinput", action="append",default=['1','2','3'],help="run all combinations")

def pytest_generate_tests(metafunc):
    if "stringinput" in metafunc.fixturenames:
        metafunc.parametrize("stringinput", metafunc.config.getoption("stringinput"))
def test_compute(stringinput):
    print("第", stringinput,"个清安")

注意此处我把配置文件的注册参数--stringinput已经删除,default参数内容也改了。

Case/test_a.py::test_compute[1] 第 1 个清安
PASSED
Case/test_a.py::test_compute[2] 第 2 个清安
PASSED
Case/test_a.py::test_compute[3] 第 3 个清安
PASSED

关于此处用法太多了,不一一举例展示,举一反三。获取可能都用不上自定义参数。

自定义传参2-引用数据

"""conftest.py"""
def pytest_addoption(parser):
    parser.addoption("--user", action="store_true",help="run all combinations")

def pytest_generate_tests(metafunc):
    if "user" in metafunc.fixturenames:
        if metafunc.config.getoption("user"):
            metafunc.parametrize("user", metafunc.module.users,
                                 ids=metafunc.module.names,
                                 scope='function')
"""test_a.py"""
names = [3, 2, 1]
users = ["清安","拾贰","北海"]

def test_compute(user):
    print("你的名字是:",user)

此处需要在配置文件中加入--user。否则运行异常。

自定义传参3-数据引用加判断

"""conftest.py"""
def pytest_addoption(parser):
    parser.addoption("--user", action="store_true",default='look',help="run all combinations")

def pytest_generate_tests(metafunc):
    if "data" in metafunc.fixturenames:
        con = metafunc.config.getoption("user")
        if con == 'look':
            metafunc.parametrize("data", metafunc.module.users,
                                 ids=metafunc.module.names,
                                 scope='function')
names = [3, 2, 1]
users = ["清安","拾贰","北海"]

@pytest.fixture
def data(request):
    return request.param

def test_compute(data):
    print("你的名字是:",data)
"""
Case/test_a.py::test_compute[3] 你的名字是: 清安
PASSED
Case/test_a.py::test_compute[2] 你的名字是: 拾贰
PASSED
Case/test_a.py::test_compute[1] 你的名字是: 北海
PASSED
"""

如果不写一个fixture用于传参,会报错哦,所以此处加了一个。配置里面的参数中可以不写--user。此外注意pytest_generate_tests中的参数是有变动的。与前两个例子不同。

场景化参数

跟上述所讲的自定义传参类似,区别不大,就是在函数方法中做了一些数据处理。

def pytest_generate_tests(metafunc):
    idlist = []
    argvalues = []
    for scenario in metafunc.cls.scenarios:
        idlist.append(scenario[0])
        items = scenario[1].items()
        argnames = [x[0] for x in items]
        argvalues.append([x[1] for x in items])
    metafunc.parametrize(argnames, argvalues, ids=idlist, scope="class")

scenario1 = ("basic", {"attribute": "value"})
scenario2 = ("advanced", {"attribute": "value2"})

class TestSampleWithScenarios:
    scenarios = [scenario1, scenario2]

    def test_demo1(self, attribute):
        print(attribute)
        assert isinstance(attribute, str)

    def test_demo2(self, attribute):
        print(attribute)
        assert isinstance(attribute, str)

这是来自官网的例子,了解即可。 pytest会自动执行pytest_generate_tests,将元组的值取出放入列表,再将元组中字典的值取出,放入列表,通过metafunc.parametrize返回,在测试函数中通过形参的方式接收。 注意:metafunc.cls.scenarios是一个列表,在TestSampleWithScenarios类中。如果解析后还是不清楚,推荐另一种方法:加打印。

def pytest_generate_tests(metafunc):
    idlist = []
    argvalues = []
    for scenario in metafunc.cls.scenarios:
        print("scenario",scenario)
        idlist.append(scenario[0])
        items = scenario[1].items()
        print(1,items)
        argnames = [x[0] for x in items]
        print(2,argnames)
        argvalues.append([x[1] for x in items])
    print(idlist)
    print(argvalues)
    metafunc.parametrize(argnames, argvalues, ids=idlist, scope="class")

这样就能知道每一步具体的值了。便于分析。打断点也是不错的方法。

类配置化参数

import pytest

def pytest_generate_tests(metafunc):
    # called once per each test function
    funcarglist = metafunc.cls.params[metafunc.function.__name__]
    print(1,funcarglist)
    argnames = sorted(funcarglist[0])
    print(2,argnames)
    metafunc.parametrize(
        argnames, [[funcargs[name] for name in argnames] for funcargs in funcarglist]
    )

class TestClass:
    # a map specifying multiple argument sets for a test method
    params = {
        "test_equals": [dict(a=1, b=2), dict(a=3, b=3)],
        "test_zerodivision": [dict(a=1, b=0)],
    }

    def test_equals(self, a, b):
        print(a,b)
        assert a == b

    def test_zerodivision(self, a, b):
        with pytest.raises(ZeroDivisionError):
            a / b

这也是一个来自官网的例子,看着复杂巴拉的,其实是真麻烦。所幸用的少,不想看的可以直接略过!

funcarglist拿到的就是TestClass中的params值,argnames对它进行一个简单的排序,在metafunc.parametrize中做具体的处理,列表推导式。先for funcargs in funcarglist循环出列表中的字典,再for name in argnames循环出列表中的元素,并以字典取值[funcargs[name]的方式将值拿出来,进行返回

最后就是传值的过程了,在程序的后端已经将返回值应该给到哪个测试用例已经处理好了。

文件读取

yaml读取参数

yaml用例:

-
  urls:
    CSDN: https://blog.csdn.net/weixin_52040868
import yaml
import pytest

"""读取Yaml文件"""
def ReadYaml(path):
    with open(path, encoding='utf8') as r:
        data = yaml.load(r, Loader=yaml.FullLoader)
    return data

"""参数化使用"""
@pytest.mark.parametrize('data',ReadYaml('./Case/case.yaml'))
def test_yaml(data):
    print(data)
"""
Case/test_a.py::test_yaml[data0] {'urls': {'CSDN': 'https://blog.csdn.net/weixin_52040868'}}
PASSED
"""

此处是简单的举例了使用步骤。Yaml的用例写法以及内容可以根据实际情况进行设定可以是列表嵌套字典。当然也可以是上述的情况,字典嵌套字典。

Excel读取参数

image.png

import pytest
import openpyxl

def ReadExcel(path):
    book = openpyxl.load_workbook(path)
    sheet = book.active
    case = sheet['A2':'B2']
    for i,j in case:
        return (i.value,j.value)

@pytest.mark.parametrize('data',ReadExcel(r"D:\python\pycase.xlsx"))
def test01(data):
    print(data)

文件读取多参数

很多人在写测试框架的时候,喜欢用pytest的parametrize的时候喜欢多参数传递。怎么操作的,以yaml为例子:

-
    -
        url1:
            CSDN: https://blog.csdn.net/weixin_52040868
    -
        URL2:
            GZH: HTTPS://

我随意修改了一下yaml的结构。使其处于一个列表中。

import yaml
import pytest

def ReadYaml(path):
    with open(path, encoding='utf8') as r:
        data = yaml.load(r, Loader=yaml.FullLoader)
    return data


@pytest.mark.parametrize('da,ta',ReadYaml('./Case/case.yaml'))
def test_yaml(da,ta):
    print(da,ta)
"""
Case/test_a.py::test_yaml[da0-ta0] {'url1': {'CSDN': 'https://blog.csdn.net/weixin_52040868'}} {'URL2': {'GZH': 'HTTPS://'}}
PASSED
"""

这样就能得到两个字典了(原数据结构式列表嵌套字典),也能直接进行字典取值了。具体如何运用,主要还是看如何组建参数。在本章中,讲解了多参数传递的例子,与此结合起来巩固巩固。

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

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

相关文章

5个关键词回顾2022年个推技术实践

作为一家数据智能服务商&#xff0c;2022年每日互动&#xff08;个推&#xff09;在为开发者和行业客户提供优质服务的同时&#xff0c;不断砥砺创新&#xff0c;追逐技术前沿。个推还持续参与开发者生态建设&#xff0c;积极总结、分享自身技术实战经验&#xff0c;面向行业输…

该如何测客户端专项测试?

整个行业现在越来越重视客户端的专项测试了。像接口的性能测试、webview 测试、H5性能分析等&#xff0c;每一项都需要测试。而对于卡顿的分析、系统资源分析、耗电量测试及弱网测试这块&#xff0c;也变得越来越重要了&#xff01;后面也会有相关的文章更新。大家可以戳此关注…

快解析远程访问解决方案——安全稳定,部署简单

我们说的远程办公通常指狭义上的远程办公&#xff0c;是指通过远程技术&#xff0c;或远程控制软件&#xff0c;对远程电脑进行操作办公&#xff0c;实现非本地办公&#xff0c;如在家办公、异地办公、移动办公等远程办公模式。这种技术的关键在于:穿透内网和远程控制的安全性。…

Wisej.NET 3.1.6 Crack

新功能 Wisej.NET 3.1 通过添加几个新的独特功能和简化的安装过程增强了里程碑 3.0 版本。 除了大量错误修复和对我们库的显着性能增强之外&#xff0c;3.1 还包括以下值得注意的新功能&#xff1a; 视觉工作室市场 Wisej.NET 现在比以往任何时候都更容易使用。或 Visual Studi…

联合证券|五大国际巨鳄集体爆雷,美股期指大跳水!

商场现已进入到雷雨季&#xff01; 周五晚间&#xff0c;花旗、摩根大通、高盛、富国和贝莱德团体爆雷。 花旗集团上一年第四季度每股收益低于预期&#xff0c;尽管营收好于预期。花旗集团Q4每股收益1.16美元&#xff0c;预期为1.17美元。财报发布之后一度暴降超3%&#xff1b;…

【机器学习之模型融合】Stacking堆叠法

目录 1、Stacking的基本思想&#x1f48d; 2、思考&#x1f48e; 3、在sklearn中实现Stacking&#x1f3af; 3.1、导入工具库和数据&#x1f455; 3.2、定义交叉验证评估函数&#x1f457; 3.3、个体学习器与元学习器的定义&#x1f357; 3.4、模型构建&#x1f36a; 4…

【Linux】创建新用户 sudo配置,添加信任

目录 一、创建新用户 二、sudo不被允许 三、添加信任用户 一、创建新用户 相关指令&#xff1a; adduser [用户名]&#xff1a;创建新用户 passwd [用户名]&#xff1a;修改用户密码 su [用户名]&#xff1a;切换到该用户 设置密码&#xff0c;重复输入两遍之后&#xff0…

大数据技术架构(组件)——Hive:环境准备1

1.0.1、环境准备1.0.1.0、maven安装1.0.1.0.1、下载软件包1.0.1.0.2、配置环境变量1.0.1.0.3、调整maven仓库打开$MAVEN_HOME/conf/settings.xml文件&#xff0c;调整maven仓库地址以及镜像地址<settings xmIns"http://maven.apache.org/SETTINGS/1.0.0"xmIns:xsi…

电脑磁盘占用率高怎么办?

Windows磁盘占用率高是一种普遍存在的问题&#xff0c;相信很多用户遇到过不止一次&#xff0c;它可能是在刚开机时、可能是在下载文件时、也可能是在开启关闭应用程序时……当磁盘占用高之后&#xff0c;您的计算机运行速度会变得像蜗牛一样缓慢&#xff0c;更糟糕的是有些电脑…

python 代码注释

文章目录写在前面使用方法plainEpytextGoogleNumpyreStructuredText相关程序包其他写在前面 如果说高效率的算法是一个项目的内核&#xff0c;那么完备的文档注释、API 接口则是项目的外壳&#xff0c;直接与客户交互。 pycharm 提供了 5 种 代码注释格式。 分别是 plain, epy…

Tslib配置文件ts.conf

默认&#xff1a; # Access plugins ################# Uncomment if you wish to use the linux input layer event interface module_raw input# For other driver modules, see the ts.conf man page# Filter plugins ################# Uncomment if first or last sample…

【运维心得】正确的校正mysql-slave及mysqldump

实践出真知&#xff0c;有些细节&#xff0c;记录下。本文不涉及主备知识&#xff0c;有需右转: https://blog.csdn.net/qq_26834611/article/details/121385550mysql 正确的dump 命令:0. 检查当前主库所在位置ip addr 查看虚拟ip所在位置 1. 备机数据库dump备份:mysqldump -ur…

【ChatGPT】注册OpenAI账号试用ChatGPT

主要参考&#xff1a; 手把手教你注册 AI 聊天机器人模型 ChatGPT&#xff1a;大体流程注册OpenAI账号试用ChatGPT指南&#xff1a; 相关网站 openai: https://beta.openai.com/signup直接登录charGPT&#xff1a;https://chat.openai.com/接入微信&#xff0c;1.2K&#xf…

OneKeyGhost工具进行备份还原windows操作系统

OneKeyGhost OneKey Ghost是一款设计专业、操作简便的绿色程序&#xff0c;能够在 Windows 下对任意分区进行一键备份、恢复&#xff0c;支持ISO文件、光盘、U盘里的GHO文件硬盘安装。 OneKeyGhost备份wind系统 系统需要包含两个磁盘&#xff0c;一个系统盘另外一个数据盘。 …

Linux-文件权限命令

用户及权限操作 d:表示文件夹&#xff0c;-&#xff1a;表示文件&#xff0c;后面每隔3个分别代表 u、g、o。 使用ls -l &#xff08;ll&#xff09;可查看文件&#xff08;目录&#xff09;的权限 使用 chmod 可修改文件权限&#xff0c;有两种使用格式&#xff1a;字母法…

剑指offer五道题,C++实现,看看自己能不能解出来。

第一道&#xff08;剑指offer46 把数字翻译成字符串&#xff09; 给定一个数字&#xff0c;我们按照如下规则把它翻译为字符串&#xff1a;0 翻译成 “a” &#xff0c;1 翻译成 “b”&#xff0c;……&#xff0c;11 翻译成 “l”&#xff0c;……&#xff0c;25 翻译成 “z”…

在产业互联网诞生之初,其仅被当成是互联网的衍生品和避风港

在流量和资本的红利已然被出清的大背景下&#xff0c;以平台经济为代表的互联网经济的发展同样被逼退到了进退维谷的境地里。如何突破以往发展模式的束缚&#xff0c;如何让互联网行业的发展重新开启新的想象空间&#xff0c;成为每一个互联网玩家必然需要思考的重要课题。于是…

python 列表生成式

列表生成式 列表生成式的结构是在一个中括号里包含一个表达式,然后是一个for语句,然后是0个或多个for或者if语句。列表表达式可以是任意的,意思是你可以在列表中放入任意类型的对象。返回结果将是一个新的列表 # 去除偶数 hh[[1,2,3],[4,5,6],[7,8,9] ]#从做往右读就行 print…

Rpc了解

1、为什么要有rpc? 因为微服务之间需要进行服务间的通信&#xff0c;不同服务之间的接口要互相调用。而常见的通信协议主要有 RPC 和 REST 协议 使用rpc的好处是&#xff1a; 引入RPC框架对我们现有的代码影响最小&#xff0c;同时又可以帮我们实现架构上的扩展 两者对比 …

【7】SCI易中期刊推荐——计算机 | 人工智能(中科院4区)

🚀🚀🚀NEW!!!SCI易中期刊推荐栏目来啦 ~ 📚🍀 SCI即《科学引文索引》(Science Citation Index, SCI),是1961年由美国科学信息研究所(Institute for Scientific Information, ISI)创办的文献检索工具,创始人是美国著名情报专家尤金加菲尔德(Eugene Garfield…