当前位置: 首页 > news >正文

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 ========================================== 

可以看到 sessionpackage 更早执行,同时更晚被销毁。

那么以上就是关于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框架的核心配置,整个框架只需一个&#xff1b…...

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

华为云AI开发平台ModelArts

华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...