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作用范围的总结


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

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

相关文章

【fisco学习记录2】多群组搭建

说明 文档参考: 多群组部署 — FISCO BCOS 2.0 v2.11.0 文档 (fisco-bcos-documentation.readthedocs.io) 多群组搭建之前,先暂停之前的单群组,并删除: cd fisco bash nodes/127.0.0.1/stop_all.sh rm -rf nodes/ 实现图&…

【NLP自然语言处理】探索注意力机制:解锁深度学习的语言理解新篇章

目录 🍔 注意力机制介绍 1.1 注意力概念 1.2 注意力计算规则 1.3 常见的注意力计算规则 🍔 什么是注意力机制 🍔 注意力机制的作用 🍔 注意力机制实现步骤 4.1 步骤 4.2 代码实现 🍔 小结 学习目标 &#x1…

美团测试面试真题学习

美团真题1–测试基础-业务场景说下你的测试用例设计 功能角度 方法论 边界值、等价类划分、错误推测法示例 输入已注册的用户名和正确的密码,验证是否登录成功;输入已注册的用户名和不正确的密码,验证是否登录失败输入未注册的用户名和任意密码&#xff…

Apache Flink Dashboard

1、Overview Apache Flink Web Dashboardhttp://110.40.130.231:8081/#/overview 这张图片显示的是Apache Flink的Web UI界面,其中包含了以下几个部分: Available Task Slots: 显示当前可用的任务槽位数量。任务槽位是指Flink集群中可用于运行任务的资…

STM32—BKP备份寄存器RTC实时时钟

1.BKP简介 BKP(Backup Registers)备份寄存器BKP可用于存储用户应用程序数据。当VDD(2.0~3.6V)电源被切断,他们仍然由VBAT(1.8~3.6V)维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位TAMP…

第5篇:DDOS病毒----应急响应之Linux实战篇

现象描述 某服务器网络资源异常,感染该木马病毒的服务器会占用网络带宽,甚至影响网络业务正常应用。 系统分析 针对日志服务器病毒事件排查情况: 在开机启动项/etc/rc.d/rc.local发现可疑的sh.sh脚本,进一步跟踪sh.sh脚本,这是一个检测病毒…

2024 kali系统2024版本,可视化界面汉化教程(需要命令行更改),英文版切换为中文版,基于Debian创建的kali虚拟机

我的界面如下所示 1. 安装 locales sudo apt install locales 2. 生成中文语言环境 sudo locale-gen zh_CN.UTF-8 如果你希望安装繁体中文,可以加入: sudo locale-gen zh_TW.UTF-8 3. 修改 /etc/default/locale 文件 确保有以下内容 LANGzh_CN.UT…

基于SpringBoot民宿预订系统小程序【附源码】

效果如下: 管理员登录界面 管理员功能界面 用户管理界面 房东管理界面 小程序首页界面 民宿房间界面 功能界面 研究背景 随着旅游业的蓬勃发展和人们对旅行体验的不断追求,民宿作为一种独特的住宿方式,因其个性化、温馨及富含地方特色的服务…

【自动驾驶汽车通讯协议】I2C(IIC)总线通讯技术详解

文章目录 0. 前言1. I2C简介2.I2C的工作原理2.1 硬件要求:2.2 半双工通信: 3. 通信时序4. 其他特性4.1 通信速率4.2 抗干扰措施4.3 注意事项 5. 在自动驾驶汽车中的应用5.1 I2C操作模式5.2 I2C的用途 6. 总结 0. 前言 按照国际惯例,首先声明&…

24.3 基于文件的服务发现模式

本节重点介绍 : 基于文件的服务发现提供了一种配置静态目标的更通用的方法可以摆脱对特定服务发现源的依赖通常的做法是调用内部CMDB的接口获取target数据,打上标签,生成json文件发给prometheus采集 基于文件的服务发现模式 解决的问题 之前手动配置…

数据结构-C语言顺序栈功能实现

栈 栈&#xff1a;类似于一个容器&#xff0c;如我们生活中的箱子&#xff0c;我们向箱子里放东西&#xff0c;那么最先放的东西是最后才能拿出来的 代码实现 #include <stdio.h> #include <stdlib.h>#define MAX_SIZE 100typedef struct {int* base; // 栈底指针…

工具篇-完整的 Git 项目管理工具教程(在命令框中使用 Git、在 IDEA 中使用 Git)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Git 概述 2.0 Git 的安装和配置 3.0 获取本地仓库 3.1 基础操作指令 3.2 分支 4.0 Git 远程仓库 4.1 创建远程仓库 4.2 配置 SSH 公钥 4.3 操作远程仓库 5.0 使用…

YOLO11改进|注意力机制篇|引入线性注意力机制FLAttention

目录 一、【FLA】注意力机制1.1【FLA】注意力介绍1.2【FLA】核心代码 二、添加【FLA】注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【FLA】注意力机制 1.1【FLA】注意力介绍 下图是【FLA】的结构图&#xff0c;让我们简单分…

探索Spring Cloud Config:构建高可用的配置中心

目录 认识Spring Cloud ConfigConfig Server读取配置文件步骤1&#xff1a;&#xff08;1&#xff09;创建config-server项目&#xff08;2&#xff09;在config-server中开启Config Server功能&#xff08;3&#xff09;在config-server配置文件进行相关配置&#xff08;4&…

防火墙的三种工作模式:路由模式、透明模式(网桥)、混合模式

防火墙作为网络安全的核心设备之一&#xff0c;扮演着至关重要的角色。它不仅能够有效防御外部网络的攻击&#xff0c;还能保护内部网络的安全。在如今复杂多样的网络环境下&#xff0c;防火墙的部署和工作模式直接影响着网络安全策略的实施效果。防火墙通常可以工作在三种模式…

数据结构-5.5.二叉树的存储结构

一.二叉树的顺序存储&#xff1a; a.完全二叉树&#xff1a; 1.顺序存储中利用了静态数组&#xff0c;空间大小有限&#xff1a; 2.基本操作&#xff1a; (i是结点编号) 1.上述图片中i所在的层次后面的公式应该把n换成i(图片里写错了)&#xff1b; 2.上述图片判断i是否有左…

如何针对项目中的技术难点准备面试?——黑马点评为例

最核心的&#xff0c;包装和准备 个人项目&#xff0c;怎么包装&#xff1f;一定要写出代码才可以吗&#xff1f; 你可以在系统A中实现就可以&#xff0c;了解其中实现的细节&#xff0c;怎么跟面试官对线等等&#xff0c;这些话术到位了之后&#xff0c;再把它融入到系统B&a…

echarts 入门

工作中第一次碰到echarts&#xff0c;当时有大哥。二进宫没办法&#xff0c;只能搞定它。 感觉生活就是这样&#xff0c;不能解决的问题总是会反复出现。通过看视频、查资料&#xff0c;完成了工作要求。写一篇Hello World&#xff0c;进行备查。 基本使用 快速上手 <!DO…

探索Theine:Python中的AI缓存新贵

文章目录 探索Theine&#xff1a;Python中的AI缓存新贵背景&#xff1a;为何选择Theine&#xff1f;Theine是什么&#xff1f;如何安装Theine&#xff1f;简单的库函数使用方法场景应用场景一&#xff1a;Web应用缓存场景二&#xff1a;分布式系统中的数据共享场景三&#xff1…

【亲测可行】ubuntu根目录空间不够,将其它盘挂载到/opt

文章目录 &#x1f315;缘起&#x1f315;从其它盘压缩出一个未分配的空间&#x1f319;从windows系统中压缩出个未分配的空间&#x1f319;从linux系统中压缩出个未分配的空间 &#x1f315;右键点击未分配的盘新建分区&#x1f315;查看分区&#x1f315;先将新分区挂载到/mn…