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循环在开始前就需要知道具体的迭代次数。例如,遍历一个列…...

机器学习和神经网络的研究与传统物理学的关系
机器学习和神经网络的研究与传统物理学的关系 机器学习和神经网络是现代科学研究中非常热门的领域,它们与传统物理学在某些方面有着密切的关系,在人类科学研究中相互影响和促进作用也越来越显著。 首先,机器学习和神经网络在物理学研究中具…...

LabVIEW提高开发效率技巧----事件触发模式
事件触发模式在LabVIEW开发中是一种常见且有效的编程方法,适用于需要动态响应外部或内部信号的场景。通过事件结构(Event Structure)和用户自定义事件(User Events),开发者可以设计出高效的事件驱动程序&am…...

Kimi AI助手重大更新:语音通话功能闪亮登场!
Kimi人工智能助手近日发布了一项令人瞩目的重大更新,其中最引人注目的是新增的语音通话功能。这一创新不仅拓展了用户与AI互动的方式,还为学习和工作场景提供了突破性的解决方案。 Ai 智能办公利器 - Ai-321.com 人工智能 - Ai工具集 - 全球热门人工智能…...

Linux——进程管理
目录 进程基础 ps 显示系统执行的进程 终止进程 kill 和 killall pstree 查看进程树 服务(service)管理 service 管理指令 服务的运行级别(runlevel) chkconfig 设置服务在不同运行级别下是否开启自启动 systemctl 管理…...

【ARM 嵌入式 编译系列 2.9 -- GCC 编译如何避免赋值判断 if ( x = 0)】
> ARM GCC 编译精讲系列课程链接 < 文章目录 GCC 编译避免赋值判断参数说明示例编译命令解决方法 GCC 编译避免赋值判断 在 GCC 编译中,为了避免误将赋值操作用于条件判断(例如 if (break_var 0x0))导致的错误,可以使用 -…...

PyTorch搭建GNN(GCN、GraphSAGE和GAT)实现多节点、单节点内多变量输入多变量输出时空预测
目录 I. 前言II. 数据集说明III. 模型3.1 GCN3.2 GraphSAGE3.3 GAT IV. 训练与测试V. 实验结果 I. 前言 前面已经写了很多关于时间序列预测的文章: 深入理解PyTorch中LSTM的输入和输出(从input输入到Linear输出)PyTorch搭建LSTM实现时间序列…...

51单片机快速入门之数码管的拓展应用2024/10/15
51单片机快速入门之数码管的拓展应用 在前面的文章中,我们已经了解到数码管的基础应用,今天来讲讲拓展应用 我们知道单个数码管分为以下 但是当我们碰到 如下这种数码管的时候又应该如何去控制呢? 这里就不得不说其拓展应用之-----------扫描显示 扫描显示: 扫描显示,又称…...

vue 音频播放控件封装
<template> <div> <audio @timeupdate="updateProgress" controls ref="audioRef" style="display: none" > <source :src="audioUrl" type="audio/mpeg" /> 您的浏览器不支持音频播放 </audio&…...

秋招面试题记录
嵌入式软件开发 网上搜集的题目 1.Static关键词的作用? static 关键字有三个主要作用: 局部变量:在函数内部,static 局部变量只初始化一次,且在函数调用结束后仍然保留其值。全局变量/函数:在文件内部&a…...

金字塔流(Pyramid Flow): 用于生成人工智能长视频的新文本-视频开源模型
在 "生成式人工智能 "中的文本生成模型和图像生成模型大行其道之后,现在该是文本-视频模型大显身手的时候了,这个列表中的新模型就是 pyramid-flow-sd3,它是一个开源模型,用于从文本或图像生成长达 10 秒的视频…...