Pytest中fixture的scope详解
pytest作为Python技术栈下最主流的测试框架,功能极为强大和灵活。其中Fixture夹具是它的核心。而且pytest中对Fixture的作用范围也做了不同区分,能为我们利用fixture带来很好地灵活性。
下面我们就来了解下这里不同scope的作用
fixture的scope定义
首先根据官网的说明,Pytest中fixture的作用范围支持5种设定,分别是function(默认值), classs, module, package, session
| 作用范围 | 说明 |
|---|---|
| function | 默认值,对每个测试方法(函数)生效,生命周期在测试方法级别 |
| class | 对测试类生效,生命周期在测试类级别 |
| module | 对测试模块生效,生命周期在模块(文件)级别 |
| package | 对测试包生效,生命周期在测试包(目录)级别 |
| session | 对测试会话生效,生命周期在会话(一次pytest运行)级别 |
下面结合代码来说明,假设目前有这样的代码结构

run_params是被测方法
def deal_params(p): print(f"input :{p}") if type(p) is int: return p*10 if type(p) is str: return p*3 if type(p) in (tuple, list): return "_".join(p) else: raise TypeError
test_ch_param, test_fixture_scope中分别定义了参数化和在测试类中的不同测试方法
import pytest@pytest.mark.parametrize("param",[10, "城下秋草", "软件测试", ("示例", "代码")])
def test_params_mark(param): print(deal_params(param))
import pytest class TestFixtureScope1: def test_int(self): assert deal_params(2) == 20 def test_str(self): assert deal_params("秋草") == "秋草秋草秋草" class TestFixtureScope2: def test_list(self): assert deal_params(["城下","秋草"]) == "城下_秋草" def test_dict(self): with pytest.raises(TypeError): deal_params({"name": "秋草"})
在公共方法文件conftest.py中定义fixture: prepare, 设置了autouse=True,即会根据fixture的设置范围自动应用
@pytest.fixture(autouse=True, scope='function')
def prepare(): print('-----some setup actions.....') yield print('-----some teardown actions!!')
这里我们分别调整prepare的scope为不同取值,然后得到对应的输出
function
(.venv) C:\Chengxiaqiucao
pytest
======================================== test session starts =========================================
collected 8 items BlogDemo/testDemo/test_ch_parm.py::test_params_mark[10] -----some setup actions.....
input :10
100
PASSED-----some teardown actions!!BlogDemo/testDemo/test_ch_parm.py::test_params_mark[城下秋草] -----some setup actions.....
input :城下秋草
城下秋草城下秋草城下秋草
PASSED-----some teardown actions!!BlogDemo/testDemo/test_ch_parm.py::test_params_mark[软件测试] -----some setup actions.....
input :软件测试
软件测试软件测试软件测试
PASSED-----some teardown actions!!BlogDemo/testDemo/test_ch_parm.py::test_params_mark[param3] -----some setup actions.....
input :('示例', '代码')
示例_代码
PASSED-----some teardown actions!!BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_int -----some setup actions.....
input :2
PASSED-----some teardown actions!!BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_str -----some setup actions.....
input :秋草
PASSED-----some teardown actions!!BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_list -----some setup actions.....
input :['城下', '秋草']
PASSED-----some teardown actions!!BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_dict -----some setup actions.....
input :{'name': '秋草'}
PASSED-----some teardown actions!!========================================= 8 passed in 0.27s ==========================================
fixture运行了8次
class
(.venv) C:\Chengxiaqiucao
pytest
======================================== test session starts =========================================
collected 8 items BlogDemo/testDemo/test_ch_parm.py::test_params_mark[10] -----some setup actions.....
input :10
100
PASSED-----some teardown actions!!BlogDemo/testDemo/test_ch_parm.py::test_params_mark[城下秋草] -----some setup actions.....
input :城下秋草
城下秋草城下秋草城下秋草
PASSED-----some teardown actions!!BlogDemo/testDemo/test_ch_parm.py::test_params_mark[软件测试] -----some setup actions.....
input :软件测试
软件测试软件测试软件测试
PASSED-----some teardown actions!!BlogDemo/testDemo/test_ch_parm.py::test_params_mark[param3] -----some setup actions.....
input :('示例', '代码')
示例_代码
PASSED-----some teardown actions!!BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_int -----some setup actions.....
input :2
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_str input :秋草
PASSED-----some teardown actions!!BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_list -----some setup actions.....
input :['城下', '秋草']
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_dict input :{'name': '秋草'}
PASSED-----some teardown actions!!========================================= 8 passed in 0.27s ==========================================
test_ch_param中的测试方法,因为直接定义在文件中,也属于类级别,所以每次赋值参数,fixture也被调用。 而 test_fixture_scope中明确定义了两个测试类,所以运行了2次
module
(.venv) C:\Chengxiaqiucao
pytest
======================================== test session starts =========================================
collected 8 items BlogDemo/testDemo/test_ch_parm.py::test_params_mark[10] -----some setup actions.....
input :10
100
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[城下秋草] input :城下秋草
城下秋草城下秋草城下秋草
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[软件测试] input :软件测试
软件测试软件测试软件测试
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[param3] input :('示例', '代码')
示例_代码
PASSED-----some teardown actions!!BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_int -----some setup actions.....
input :2
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_str input :秋草
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_list input :['城下', '秋草']
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_dict input :{'name': '秋草'}
PASSED-----some teardown actions!!========================================= 8 passed in 0.27s ==========================================
修改为module范围后,可以看到,每个模块文件调用了一次fixture
package
(.venv) C:\Chengxiaqiucao
pytest
======================================== test session starts =========================================
collected 8 items BlogDemo/testDemo/test_ch_parm.py::test_params_mark[10] -----some setup actions.....
input :10
100
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[城下秋草] input :城下秋草
城下秋草城下秋草城下秋草
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[软件测试] input :软件测试
软件测试软件测试软件测试
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[param3] input :('示例', '代码')
示例_代码
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_int input :2
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_str input :秋草
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_list input :['城下', '秋草']
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_dict input :{'name': '秋草'}
PASSED-----some teardown actions!!========================================= 8 passed in 0.27s ==========================================
修改为package, 这是因为两个测试文件位于同一个package内, 所以运行了一次
session
(.venv) C:\Chengxiaqiucao
pytest
======================================== test session starts =========================================
collected 8 items BlogDemo/testDemo/test_ch_parm.py::test_params_mark[10] -----some setup actions.....
input :10
100
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[城下秋草] input :城下秋草
城下秋草城下秋草城下秋草
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[软件测试] input :软件测试
软件测试软件测试软件测试
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[param3] input :('示例', '代码')
示例_代码
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_int input :2
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_str input :秋草
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_list input :['城下', '秋草']
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_dict input :{'name': '秋草'}
PASSED-----some teardown actions!!========================================= 8 passed in 0.27s ==========================================
最后,当设置为session时,也就是运行pytest的一次执行会话,才会触发一次fixture调用
所以可以看到,我们通过fixture的不同scope定义,可以根据需要,来确定我们编写的fixture夹具的作用范围。有很好的灵活性
复杂fixture的scope灵活定义
有时在实际使用的时候,特别是我们的一些fixture初始化工作比较复杂但同时在不同作用范围下都可能会用到,这时如果仅仅因为针对不同的作用范围,就要编写多个不同的fixture,代码就显得比较冗余。这时可以怎么处理呢? 其实可以利用上下文contextmanager来灵活实现
比如我们再编写一个fixture的基本代码上下文:
@contextmanager
def fixture_base(): print('~~~~~base fixture setup actions.....') yield print('~~~~~base fixture teardown actions!!')
然后针对不同的fixture,我们就可以根据不同的scope来定义不同的fixture并调用这里的context实现。 比如我们再定义一个scope为package的fixture
@pytest.fixture(autouse=False, scope='package')
def fixture_module(): """ 对于复杂的fixture但希望灵活处理scope,可以将公共代码放到一个contextmanager中, 再针对不同scope定义相关对应fixture """ with fixture_base() as result: yield result
👍👍这个方法来自pytest的社区总结,原始问题链接
不同scope的执行顺序
上面例子中我们其实看到package和session的执行效果,因为测试方法都在同一个package中,所以效果上没什么差异。但其实不同scope也是有执行顺序的
顺序总结如下:
session > package > module > class > function
这里增加到两个fixture以后,执行的结果:
(.venv) C:\Chengxiaqiucao
pytest
======================================== test session starts =========================================
collected 8 items BlogDemo/testDemo/test_ch_parm.py::test_params_mark[10] -----some setup actions.....
~~~~~base fixture setup actions.....
input :10
100
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[城下秋草] input :城下秋草
城下秋草城下秋草城下秋草
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[软件测试] input :软件测试
软件测试软件测试软件测试
PASSED
BlogDemo/testDemo/test_ch_parm.py::test_params_mark[param3] input :('示例', '代码')
示例_代码
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_int input :2
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope1::test_str input :秋草
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_list input :['城下', '秋草']
PASSED
BlogDemo/testDemo/test_fixture_scope.py::TestFixtureScope2::test_dict input :{'name': '秋草'}
PASSED~~~~~base fixture teardown actions!!
-----some teardown actions!!========================================= 8 passed in 0.27s ==========================================
可以看到 session 比 package 更早执行,同时更晚被销毁。
那么以上就是关于pytest scope作用范围的总结
相关文章:
Pytest中fixture的scope详解
pytest作为Python技术栈下最主流的测试框架,功能极为强大和灵活。其中Fixture夹具是它的核心。而且pytest中对Fixture的作用范围也做了不同区分,能为我们利用fixture带来很好地灵活性。 下面我们就来了解下这里不同scope的作用 fixture的scope定义 首…...
Springboot 接入 WebSocket 实战
Springboot 接入 WebSocket 实战 前言: WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。 简单理解: 1,常见开发过程中我们知道 Http协议,客户端…...
数据结构之红黑树的实现
红黑树的实现 1. 红⿊树的概念1.1 红⿊树的规则:1.2 思考⼀下,红⿊树如何确保最⻓路径不超过最短路径的2倍的?1.3 红⿊树的效率: 2. 红⿊树的实现2.1 红⿊树的结构2.2 红⿊树的插⼊2.2.1 红⿊树树插⼊⼀个值的⼤概过程2.2.2 情况1…...
智能工厂的设计软件 中的AI操作系统的“三维时间”(历时/共时/等时)构建的“能力成熟度-时间规模”平面
本文要点 “智能工厂的设计软件提出 “三维时间”的一个时间立方体(cube)。 “三维时间”的概念--历时diachronic(一维的)、共时synchronic(二维的)和等时isochronic(三维的)。 即…...
Spring Boot常见错误与解决方法
White graces:个人主页 🙉专栏推荐:Java入门知识🙉 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 目录 创建第一个SpringBoot项目 SpringBoot项目各个…...
Mac中安装以及配置adb环境
一、adb介绍 Android 调试桥 (Android Debug Bridge) 是一种功能多样的命令行工具,可让您与设备进行通信。adb 命令可用于执行各种设备操作,例如安装和调试应用。adb 提供对 Unix shell(可用来在设备上运行各种命令)的访问权限。…...
WebGL着色器语言中各个变量的作用
1、attribute变量 用于接收顶点数据,只能在顶点着色器中声明和使用。 attribute vec3 a_position; 2、uniform变量 用于在JavaScript代码中设置并在着色器程序中保持不变的值,可以在顶点着色器和片元着色器中声明和使用。但是要保证变量名唯一&#…...
Canmv k230 C++案例1——image classify学习笔记 初版
00 简介 用C编写代码的比mircopython要慢很多,需要编译开发环境,同时使用C更接近底层,效率利用率应该也是更高的,就是需要学习更多的内容,因为从零开始因此比较比较耗时。 注:以下为个人角度的理解&#x…...
vs2022 dump调试
程序中加入了捕获dump得代码,那么当程序crash时,通常可以捕获到dump文件。当然,也有一些崩溃是捕获不到的。本文就捕获到的dump文件,总结一下调试的流程。 前提:exe,pdb,dump 3者是放在同一目录…...
OpenCV高级图形用户界面(11)检查是否有键盘事件发生而不阻塞当前线程函数pollKey()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 轮询已按下的键。 函数 pollKey 无等待地轮询键盘事件。它返回已按下的键的代码或如果没有键自上次调用以来被按下则返回 -1。若要等待按键被按…...
nvm安装,node多版本管理
卸载nodejs win R 输入 appwiz.cpl 删除 node.js查看node.js安装路径是否有残留,有就删除文件夹 删除下列路径文件,一定要检查,没删干净,nvm安装会失败 C:\Program Files (x86)\NodejsC:\Program Files\NodejsC:\Users{User}\…...
ThingsBoard规则链节点:Assign To Customer节点详解
引言 分配给客户节点概述 用法 含义 应用场景 实际项目运用示例 结论 引言 在物联网(IoT)解决方案中,ThingsBoard平台以其高效的数据处理能力和灵活的设备管理功能而著称。其中,规则引擎是该平台的一个核心组件,…...
自监督行为识别-时空线索解耦(论文复现)
自监督行为识别-时空线索解耦(论文复现) 本文所涉及所有资源均在传知代码平台可获取 文章目录 自监督行为识别-时空线索解耦(论文复现)引言论文概述核心创新点双向解耦编码器跨域对比损失的构建结构化数据增强项目部署准备工作数据…...
MyBatisPlus:自定义SQL
由于SQL不能写在业务层,所以可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分 ①基于Wrapper 构建Where条件 Testpublic void test7(){//需求:将id满足ids的数据项的balance字段减200int amount200;List…...
变电站谐波治理设备有哪些
在变电站中,由于非线性负载(如电力电子设备、变频器等)会引入谐波,对电网造成干扰,因此需要进行谐波治理。以下是常见的变电站谐波治理设备及其特点: 1、静止无功发生器(SVG) 工作原…...
Mybatis全局配置介绍
【mybatis全局配置介绍】 mybatis-config.xml,是MyBatis的全局配置文件,包含全局配置信息,如数据库连接参数、插件等。整个框架中只需要一个即可。 1、mybatis全局配置文件是mybatis框架的核心配置,整个框架只需一个;…...
error: cannot find symbol import android.os.SystemProperties;
背景:AS独立编译系统工程应用,使用了hide接口,导致编译不过。 尽管使用了framework.jar依赖。依然编译不过,导致各种类找不到。 例如: /SettingsLib/src/main/java/com/android/settingslib/location/RecentLocatio…...
债券市场金融基础设施 (2020版)
前言:我国债券市场格局简介 我国金融市场主要包括货币市场、资本市场、外汇市场、金融衍生工具市场等,其中,资本市场是金融市场重要组成部分,承担着实体经济直接融资的重责,做大做强资本市场对整个国民经济具有重要意义。债券市场是资本市场两大组成部分之一,对提高直接…...
OpenCV高级图形用户界面(8)在指定的窗口中显示一幅图像函数imshow()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在指定的窗口中显示一幅图像。 函数 imshow 在指定的窗口中显示一幅图像。如果窗口是以 cv::WINDOW_AUTOSIZE 标志创建的,图像将以原…...
for循环和while循环的区别
for循环和while循环的主要区别在于使用场景和结构。for循环适合已知循环次数的情况,而while循环则更灵活,适用于条件动态变化的情况。 for循环的特点 1. 已知迭代次数:for循环在开始前就需要知道具体的迭代次数。例如,遍历一个列…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
