pytest-fixture

资料来源:虫师2020的个人空间-虫师2020个人主页-哔哩哔哩视频

支持类似unittest风格的fixture,即setup和teardown

class类中的方法分类

类方法可以直接调用,需要添加装饰器,修改类中的变量

实例方法,需要先实例化,修改实例方法内的变量

静态方法可以直接调用

class A:name = 'jerry'#类方法:修改类变量@classmethoddef motify_name(cls):return cls.name+'class'# 初始化方法def __init__(self):self.name = 'tom'#实例方法 instance Method:修改实例变量def hello(self):return self.name+'new'#静态方法@staticmethoddef static_method(x,y):return x+yif __name__ == '__main__':# 类方法可以直接调用motify = A.motify_name()print("classmethod:",motify)#静态方法可以直接调用result = A.static_method(3, 4)print("static_method:", result)#实例方法,需要先实例化a = A()new_name = a.hello()print("类中对象的属性",a.name)print("instance Method:",new_name)

class 级别

import pytestdef multiply(a, b):"""Return the product of two numbers."""return a * b# Test fixture for the multiply function
class TestMultiply:@classmethoddef setup_class(cls):print("setup_class(): Executed before any method in this class")@classmethoddef teardown_class(cls):print("teardown_class(): Executed after all methods in this class")def setup_method(self):print("setup_method(): Executed before each test method")def teardown_method(self):print("teardown_method(): Executed after each test method")def test_multiply_3(self):"""Test multiply with two integers."""print("Executing test3")assert multiply(3, 4) == 12def test_multiply_4(self):"""Test multiply with an integer and a string (should fail)."""print("Executing test4")# Note: This test will raise a TypeError due to incompatible types.assert multiply(3, 'a') == 'aaa'

module级别

import pytest# 功能函数
def multiply(a, b):return a * b# ====== fixture ======
def setup_module(module):print("setup_module():在整个模块之前执行",module)def teardown_module(module):print("teardown_module():在整个模块之后执行",module)def setup_function(function):print("setup_function():在每个方法之前执行",function)def teardown_function(function):print("teardown_function():在每个方法之后执行",function)def test_multiply_1():print("正在执行test1")assert multiply(3, 4) == 12def test_multiply_2():print("正在执行test2")assert multiply(3, 'a') == 'aaa'class TestMultiply:def test_multiply_4(self):"""Test multiply with an integer and a string (should fail)."""print("Executing test4")# Note: This test will raise a TypeError due to incompatible types.assert multiply(3, 'a') == 'aaa'

fixture的简单用例

单个fixture

用fixture之前的原代码

import pytest# @pytest.fixture()
def init_env():print("this is fixture")return Truedef test_case(init_env):if init_env is True:print("test case")if __name__ == '__main__':ie = init_env()test_case(init_env=ie)

 fixture装饰后

import pytest@pytest.fixture()
def init_env():print("this is fixture")return Truedef test_case(init_env):if init_env is True:print("test case")

多个fixture

import pytest@pytest.fixture()
def first():print("this is fixture")return "a"@pytest.fixture()
def second():print("this is fixture")return 2@pytest.fixture()
def oder(first,second):return first * second@pytest.fixture()
def expected():return "aa"def test_string(oder,expected):print(oder)assert oder == expected

autouse = True,被装饰的函数自动执行

import pytest@pytest.fixture()
def first():print("this is fixture")return "a"@pytest.fixture()
def second(first):print("this is 2fixture")return []@pytest.fixture(autouse=True)
def order(second,first):print("自动执行")return second.append(first)def test_string(second,first):assert second == [first]

使用范围

scope:=module,session,class,function;

function:每个test都运行,默认是function的scope ,

class:每个 class的所有test只运行一次;

module:每个module的所有test只运行一次;

session:每个session只运行一次

返回参数

在 pytest 中,一个 fixture 可以返回任意数量的数据,包括多个参数。然而,当你想要通过 request 对象在 fixture 内部访问参数化装饰器 (@pytest.mark.parametrize) 提供的参数时,你需要确保正确地设置 fixture 和参数化装饰器之间的关系。在参数化装饰器中直接定义多个参数,并在测试函数中接收它们。然后在 fixture 中,可以直接返回一个元组或者一个字典,其中包含了多个值。

下面是一个示例,展示了如何在一个 fixture 中返回两个参数:

import pytest# 这个 fixture 返回一个元组,其中包含两个值
@pytest.fixture
def two_values(request):# 获取参数化装饰器提供的参数first_value = request.param[0]second_value = request.param[1]# 返回一个包含两个值的元组return (first_value, second_value)# 使用 @pytest.mark.parametrize 装饰器提供多组参数
# 直接在测试函数中接收两个参数
@pytest.mark.parametrize("first_value, second_value", [(1, 2), (3, 4)])
def test_with_two_values(first_value, second_value):assert first_value < second_value

在这个例子中,two_values fixture 返回一个包含两个值的元组。我们使用 @pytest.mark.parametrize 装饰器来提供两组参数 (1, 2)(3, 4)。然后在测试函数 test_with_two_values 中,我们接收 two_values fixture 的结果,并同时接收 first_valuesecond_value 参数,这些参数是由参数化装饰器提供的。

Teardown - yield 

迭代器

#被测试类所实现功能
import pytestclass Counter:def __init__(self):self.value = 0def increment(self):self.value += 1def get_value(self):return self.valueif __name__ == '__main__':c = Counter()c.increment()c.increment()c.increment()c.increment()print(c.get_value())

import pytestclass Counter:def __init__(self):self.value = 0def increment(self):self.value += 1def get_value(self):return self.value@pytest.fixture
def counter():#setupc = Counter()print("setup_value:",c.value)yield c  #返回实例 c#还原数据,用例结束后实现c.value=0print("teardonw_value:",c.value) def test_counter(counter):print('test-start')assert counter.get_value() == 0counter.increment()assert counter.get_value() == 1counter.increment()assert counter.get_value() == 2

终结器 finalizer

同上,value增加后再重置为0

import pytestclass Counter:def __init__(self):self.value = 0def increment(self):self.value += 1def get_value(self):return self.value@pytest.fixture
def counter(request):#request 参数不需要传值#setupc = Counter()print("setup_value:",c.value)def reset_counter():#还原数据c.value = 0print("teardown_value:",c.value)request.addfinalizer(reset_counter)return cdef test_counter(counter):print('test-start')assert counter.get_value() == 0counter.increment()assert counter.get_value() == 1counter.increment()assert counter.get_value() == 2

fixture装饰的方法的request

在PyTest中,`request`对象是一个特殊的fixture,它提供了对当前测试请求的访问。当你在自定义的fixture函数中使用`request`作为参数时,你实际上可以获得当前测试的详细信息,并且可以利用这些信息来定制fixture的行为。`request`对象提供了很多有用的方法和属性,使你能够更灵活地设置和清理测试环境。

在你提供的fixture示例中,`request`对象被用来添加一个finalizer,即一个在测试结束后自动调用的清理函数。`request.addfinalizer()`方法接受一个可调用对象作为参数,并确保在测试完成时调用它,即使测试失败或抛出了异常。这使得你可以在测试结束后执行一些必要的清理工作,比如关闭文件、重置状态、释放资源等。

以下是一些`request`对象常用的方法和属性:

- `request.param`:如果测试函数使用了参数化装饰器`@pytest.mark.parametrize`,则`request.param`将包含当前测试迭代的参数值。
- `request.function`:返回当前正在运行的测试函数。
- `request.cls`:如果测试函数属于一个测试类,则返回这个测试类。
- `request.module`:返回包含当前测试的模块。
- `request.config`:返回PyTest配置对象,可以从中获取命令行选项和其他配置信息。
- `request.getfixturevalue(name)`:获取其他fixture的返回值。
- `request.cached_setup`:用于缓存setup过程的结果,避免重复执行相同的setup步骤。

总的来说,`request`对象在自定义fixture中提供了一种强大的机制,用于根据测试的具体需求动态调整fixture的行为,从而实现更加复杂的测试场景支持和资源管理。

参数化

10_pytest之fixture装饰器使用(下)_哔哩哔哩_bilibili

直接参数化(Direct Parametrization)

直接参数化是最直观的参数化方法,它在测试函数上使用 @pytest.mark.parametrize 装饰器,直接指定测试函数的参数及其值。这种方法适用于当你的参数可以直接在测试函数中使用,不需要额外的处理或准备。

import pytest@pytest.mark.parametrize("input, expected", [("3+5", 8),("2+4", 6),("-1+1", 0),
])
def test_eval(input, expected):assert eval(input) == expected

间接参数化(Indirect Parametrization)

间接参数化则是通过 fixture 来提供参数,这样可以在参数化测试之前执行一些预处理或设置工作。当你需要在测试前做某些准备工作,比如数据库连接、文件读取、网络请求等,或者当参数的准备较为复杂时,使用间接参数化就很有必要了。

import pytest@pytest.fixture
def prepared_input(request):input_str, expected = request.param# 执行一些预处理,比如从数据库获取数据return input_str, expected@pytest.mark.parametrize("prepared_input", [("3+5", 8),("2+4", 6),("-1+1", 0),
], indirect=True)
def test_eval(prepared_input):input_str, expected = prepared_inputassert eval(input_str) == expected

pytest.mark.parametrize的使用

基本使用

@pytest.mark.parametrize("argnames", argvalues)
def test_function(argnames):# 测试逻辑

argnames 是一个字符串,包含了测试函数参数的名称,多个参数用逗号分隔。

argvalues 是一个列表,其中的每一个元素都是一组参数值,对应于 argnames 中的参数。

import pytest@pytest.mark.parametrize("x, y, expected", [(1, 2, 3),(5, 3, 8),(-1, -1, -2),
])
def test_addition(x, y, expected):assert x + y == expected

使用 ids

每组参数指定一个标识符(id),这样可以使得测试报告更加可读。ids 应该是一个与 argvalues 同长度的列表,每个元素对应一组参数的描述。

@pytest.mark.parametrize("x, y, expected", [(1, 2, 3),(5, 3, 8),(-1, -1, -2),
], ids=["positive_numbers", "larger_positive_numbers", "negative_numbers"])
def test_addition(x, y, expected):assert x + y == expected

复杂参数

如果参数值本身是复杂的结构,如列表或字典,你可以直接在 argvalues 中使用这些结构。

@pytest.mark.parametrize("data", [{"input": [1, 2, 3], "expected": 6},{"input": [4, 5, 6], "expected": 15},
])
def test_sum_list(data):assert sum(data["input"]) == data["expected"]

间接参数化

间接参数化允许你使用 fixture 作为参数源,这样可以在测试函数运行前进行一些初始化工作。要使用间接参数化,你只需在 argnames 后面添加 indirect=True

import pytest@pytest.fixture
def prepared_data(request):if request.param == "case1":return {"input": [1, 2, 3], "expected": 6}elif request.param == "case2":return {"input": [4, 5, 6], "expected": 15}@pytest.mark.parametrize("prepared_data", ["case1", "case2"], indirect=True)
def test_sum_list(prepared_data):assert sum(prepared_data["input"]) == prepared_data["expected"]

fixture两个方法传递参数

直接在 Fixture 方法中调用另一个 Fixture:

如果一个 fixture 需要依赖另一个 fixture 的输出,你可以在一个 fixture 的实现中直接调用另一个 fixture。这是最直接的方式,但要注意保持依赖关系清晰,避免过多的耦合。

import pytest@pytest.fixture
def fixture_a():return "A"@pytest.fixture
def fixture_b(fixture_a):# 使用 fixture_a 的输出return fixture_a + "B"def test_example(fixture_b):assert fixture_b == "AB"
使用 request 对象间接获取参数

当你使用 @pytest.mark.parametrize 装饰器时,可以在 fixture 中使用 request 对象来获取参数化装饰器提供的参数。

import pytest@pytest.fixture
def fixture_a(request):# 从 request.param 获取参数return request.param@pytest.fixture
def fixture_b(fixture_a):return fixture_a + "B"@pytest.mark.parametrize("fixture_a", ["A"], indirect=True)
def test_example(fixture_b):assert fixture_b == "AB"
使用 Indirect 参数化

如果你需要将一个 fixture 的输出作为另一个 fixture 的参数,你可以使用 indirect 参数化。这允许你将一个 fixture 的返回值直接作为另一个 fixture 的参数。

import pytest@pytest.fixture
def fixture_a():return "A"@pytest.fixture
def fixture_b(fixture_a):return fixture_a + "B"@pytest.mark.parametrize("fixture_a", ["A"], indirect=True)
@pytest.mark.parametrize("fixture_b", ["AB"], indirect=True)
def test_example(fixture_a, fixture_b):assert fixture_a + "B" == fixture_b

通常你不需要为每个 fixture 单独使用 @pytest.mark.parametrize,因为这可能导致不必要的重复测试。更常见的是,一个 fixture 依赖于另一个 fixture 的输出,如第一个例子所示。

使用 Fixture 返回复杂数据结构

如果一个 fixture 需要返回复杂的数据结构,如字典或元组,你可以在测试函数中直接解构这些数据结构。

import pytest@pytest.fixture
def complex_fixture():return {"part_a": "A", "part_b": "B"}def test_example(complex_fixture):part_a, part_b = complex_fixture.values()assert part_a + part_b == "AB"
Fixture接收外部参数

让第二个 fixture 既接收第一个 fixture 的返回值,又接收一个额外的参数

import pytest# 第一个 fixture
@pytest.fixture
def first_fixture():return "Hello from first fixture"# 第二个 fixture,它接收第一个 fixture 的返回值和一个额外的参数
@pytest.fixture
def second_fixture(first_fixture, extra_param):return first_fixture + ", " + extra_param# 使用 indirect=True 指定 extra_param 应该间接地传递给 second_fixture
@pytest.mark.parametrize("extra_param", ["World"], indirect=["second_fixture"])
def test_example_with_params(second_fixture):assert second_fixture == "Hello from first fixture, World"

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

达梦数据库系列—29. DTS迁移ORACLE到DM

目录 1.ORACLE源端信息 2.DM目的端信息 3.DTS 迁移评估 4.数据库迁移 4.1 Oracle 源端数据库准备 4.2 目的端达梦数据库准备 初始化参数设置 兼容性参数设置 表空间规划 用户规划 创建迁移用户和表空间 4.3迁移步骤 创建迁移 配置数据源 配置迁移对象及策略 开…

TCP客户端connect断线重连

文章目录 TCP客户端connect断线重连1、为什么要断线重连2、实现代码 TCP客户端connect断线重连 1、为什么要断线重连 客户端会面临服务器崩溃的情况&#xff0c;我们可以试着写一个客户端重连的代码&#xff0c;模拟并理解一些客户端行为&#xff0c;比如游戏客户端等. 考虑到…

【Git】merge合并分支

两个分支未修改同一个文件的同一处位置: Git自动合并 两个分支修改了同一个文件的同一处位置:产生冲突 例&#xff1a; 在master分支修改了main同时&#xff0c;feat分支也修改了相同的文件 合并的时候就会产生冲突 解决方法: Step1- 手工修改冲突文件&#xff0c;合并冲突内容…

go语言day15 goroutine

Golang-100-Days/Day16-20(Go语言基础进阶)/day17_Go语言并发Goroutine.md at master rubyhan1314/Golang-100-Days GitHub 第2讲-调度器的由来和分析_哔哩哔哩_bilibili 一个进程最多可以创建多少个线程&#xff1f;-CSDN博客 引入协程 go语言中内置了协程goroutine&#…

星环科技携手东华软件推出一表通报送联合解决方案

随着国家金融监督管理总局“一表通”试点工作的持续推进&#xff0c;星环科技携手东华软件推出了基于星环科技分布式分析型数据库ArgoDB和大数据基础平台TDH的一表通报送联合解决方案&#xff0c;并已在多地实施落地中得到充分验证。 星环科技与东华软件作为战略合作伙伴&…

论文阅读【检测】:Facebook ECCV2020 | DETR

文章目录 论文地址AbstractMotivation模型框架详细结构小结 论文地址 DETR Abstract 提出了一种将目标检测视为直接集预测问题的新方法。简化了检测pipeline&#xff0c;有效地消除了许多手工设计的组件的需求&#xff0c;例如非最大抑制过程或锚生成&#xff0c;这些组件明…

802.11无线网络权威指南(二):无线帧结构

802.11无线网络权威指南&#xff08;二&#xff09;&#xff1a;无线帧结构 无线协议桢的三种类型无线网络帧结构完整帧格式control frameDuration/IDAddressSequence ControlQoS ControlHT Control 字段Frame Body 帧体FCS 校验域 帧细节管理帧控制帧RTS 帧CTS 帧ACK 帧格式PS…

ceph log内容解析

log内容构造 如osd的一条log 分别表示 时间戳 线程id 日志等级 子模块 内容实体 剖析源码实现 每条log都是由一个Entry构成 定义在src/log/entry.h中 Entry(short pr, short sub) :m_stamp(clock().now()), // 打印日志时的时间戳m_thread(pthread_self()), // 打印日志的线…

redis的持久化方式

目录 1. 什么是持久化&#xff1f; 2. redis实现持久化的方式 2.1 什么是RDB&#xff1f; 2.2 什么时候会触发RDB模式&#xff1f; 2.2.1 手动触发 2.2.2 自动触发 2.3 什么是Aof&#xff1f; 2.3.1 开启Aof 2.4 RBD和AOF的区别 1. 什么是持久化&#xff1f; 把内存中…

el-table列的显示与隐藏

需求&#xff1a;实现 表字段的显示与隐藏。效果图 代码实现 写在前面 首先 我部分字段有自定义的排序逻辑&#xff0c;和默认值或者 数据的计算 所以是不能简单的使用 v-for 循环column 。然后 我需要默认展示一部分字段&#xff0c;并且 当表无数据时 提示不能 显示隐藏 …

AIGC Kolors可图IP-Adapter-Plus风格参考模型使用案例

参考: https://huggingface.co/Kwai-Kolors/Kolors-IP-Adapter-Plus 代码环境安装: git clone https://github.com/Kwai-Kolors/Kolors cd Kolors conda create --name kolors python=3.8 conda activate kolors pip install -r requirements.txt python3 setup.py install…

mybatis一对多 多对多

一对一 方式一: ,在result的property属性用user.XXX 方式二:把user对象的属性用resultMap标签包含在association标签里,user的id做id标签,特点是返回值是对象的标识,而集合是collection 一对多 在user类加了个订单的集合,表示一个用户有多个订单 这接口当然是user的 分为re…

PWM信号转模拟信号转换器GP8101/GP8101M

前言&#xff1a; 各位大佬&#xff0c;听说过PAC吗&#xff1f;PAC (PWM to Analog Converter)。 今天介绍一个小众的转换芯片&#xff0c;PWM转模拟信号的&#xff0c;有一定的应用场景,单价一元多。这种芯片隔离PWM还是很容易的。 0%-100% PWM to 0-5V/0-10V SOP8封装的GP…

HarmonyOS三方库的使用

系统组件难以提供比较优秀的界面&#xff0c;需要第三方库来实现一些比较好看的界面效果 三方库的获取&#xff1a; 开源社区支持OpenHarmony-TPC 和 Openharmony三方库中心仓 先目前已经拥有各种各样的三方库&#xff0c;包括UI 图片 动画 网络 数据存储 工具类 多媒体 安全等…

redis数据类型介绍

Redis 支持多种数据类型&#xff0c;包括&#xff1a; 1.字符串&#xff08;String&#xff09;&#xff1a;最简单的数据类型&#xff0c;可以存储字符串、数字等。 2.哈希&#xff08;Hash&#xff09;&#xff1a;类似于 Map&#xff0c;可以存储键值对&#xff0c;其中键值…

Go语言编程 学习笔记整理 第2章 顺序编程 后半部分

1.流程控制 1.1 条件语句 if a < 5 { return 0 } else { return 1 } 注意&#xff1a;在有返回值的函数中&#xff0c;不允许将“最终的”return语句包含在if...else...结构中&#xff0c; 否则会编译失败&#xff01;&#xff01;&#xff01; func example(x int) i…

leetcode 2236.判断根节点是否等于字节点

1.题目要求: 给你一个 二叉树 的根结点 root&#xff0c;该二叉树由恰好 3 个结点组成&#xff1a;根结点、左子结点和右子结点。如果根结点值等于两个子结点值之和&#xff0c;返回 true &#xff0c;否则返回 false 。2.思路: 直接数组前序遍历&#xff0c;然后判断后面两个…

【C++】:红黑树深度剖析 --- 手撕红黑树!

目录 前言一&#xff0c;红黑树的概念二&#xff0c;红黑树的性质三&#xff0c;红黑树节点的定义四&#xff0c;红黑树的插入操作4.1 第一步4.2 第二步4.3 插入操作的完整代码 五&#xff0c;红黑树的验证六&#xff0c;实现红黑树的完整代码五&#xff0c;红黑树与AVL树的比较…

【接口自动化_08课_Pytest+Yaml+Allure框架】

上节课一些内容 的补充 1、openxl这个方法&#xff0c;第一个元素是从1开始的&#xff0c;不是从0开始 回写的列在程序里写的是11&#xff0c;是因为是固定值 一、1. Yaml入门及应用 1、什么是yaml YAML&#xff08;/ˈjməl/&#xff0c;尾音类似camel骆驼&#xff09;是一…

单向链表

目录 思维导图&#xff1a; 学习内容&#xff1a; 1. 链表的引入 1.1 顺序表的优缺点 1.1.1 优点 1.1.2 不足 1.1.3 缺点 1.2 链表的概念 1.2.1 链式存储的线性表叫做链表 1.2.2 链表的基础概念 1.3 链表的分类 2. 单向链表 2.1 节点结构体类型 2.2 创建链表 2.…