pytest fixture基础大全详解

一、介绍

作用

fixture主要有两个作用:

  • 复用测试数据和环境,可以减少重复的代码;
  • 可以在测试用例运行前和运行后设置和清理资源,避免对测试结果产生影响,同时也可以提高测试用例的运行效率。

优势

pytest框架的fixture测试夹具就相当于unittest框架的setup、teardown,但相对之下它的功能更加强大和灵活。

  • 命名方式灵活,不局限于 setup 和teardown 这几个命名。
  • conftest.py 配置里可以实现数据共享,不需要 import 就能自动找到fixture。
  • scope=“session” 可以实现多个.py 跨文件共享前置。(fixture为module时,在当前.py脚本里面所有用例开始前只执行一次。fixture为session级别是可以跨.py模块调用的,也就是当我们有多个.py文件的用例的时候,如果多个用例只需调用一次fixture,那就可以设置为scope=“session”,并且写到conftest.py文件里。)
  • 可以实现unittest不能实现的功能,比如unittest中的测试用例和测试用例之间是无法传递参数和数据的,但是fixture却可以解决这个问题

与传统 setup/teardown 的对比

特性fixturesetup/teardown
代码复用高(通过函数和参数化)低(需继承或重复代码)
依赖关系显式(通过参数声明)隐式(通过类结构)
执行顺序灵活(支持复杂依赖图)固定(setup → test → teardown)
作用域控制支持多级作用域(function/module/session)仅支持类或方法级别
参数化测试原生支持需要额外代码

二、第一个fixture

#!/usr/bin/env python
# encoding: utf-8
'''
@desc   : 第一次使用fixture简单示例
'''
import pytest# 用例预置数据
@pytest.fixture
def first_fix():return 'hello '# 测试用例
def test_01(first_fix):# 用例步骤first_fix +='fixture!'print(first_fix)if __name__ == '__main__':pytest.main(['-s', 'test_first_fix.py'])

控制台输出:
在这里插入图片描述

对比:

# 旧方法,不适用pytest的实现方法
def first_fix():return 'hello '# 测试用例
def test_01(first_fix):# 用例步骤first_fix +='fixture!'print(first_fix)ffix = first_fix()
test_01(ffix)

控制台:
hello fixture!

三、fixture互相调用

#!/usr/bin/env python
# encoding: utf-8
'''
@Author  : 草木零
@Software: PyCharm
@File    : test_fix_callEachOther.py
@Time    : 2023/8/22 18:39
@desc   : fixture互相调用
'''
import pytest# @pytest.fixture()不传递参数时,写法效果相当于@pytest.fixture
@pytest.fixture()
def fix01():return {'name': 'Erin', 'age': 26}
@pytest.fixture
def fix02(fix01):fix01['city'] = 'Guangzhou'return fix01
@pytest.fixture
def fix03(fix01):fix01 = [fix01]fix01.append({'name': 'John', 'age': 13})return fix01
def test_case01(fix02, fix03):print(fix02)print(fix03)
# def test_case02(fix03):
#     print(fix03)
if __name__ == '__main__':pytest.main(['-sv', 'test_fix_callEachOther.py'])

控制台输出:
在这里插入图片描述

不使用pytest的旧方法实现对比:

def fix01():return {'name': 'Erin', 'age': 26}def fix02(fix01):fix01['city'] = 'Guangzhou'return fix01def test_call_each_other(fix02):print(fix02)fix1 = fix01()
fix2 = fix02(fix1)
test_call_each_other(fix2)

控制台输出:
在这里插入图片描述

四、装饰器@pytest.mark.usefixtures()

叠加使用usefixtures:如果一个方法或者一个class用例想要同时调用多个fixture,可以使用pytest.mark.usefixtures()进行叠加。注意叠加顺序,先执行的放底层,后执行的放上层。见下例。

在类上使用usefixtures,类中的用例就不要再重复使用了

下例展示了三种使用,

  1. 用于函数

  2. 用于类@pytest.mark.usefixtures('fix1','fix2')

  3. 用于类叠加使用

    @pytest.mark.usefixtures(‘fix1’)
    @pytest.mark.usefixtures(‘fix2’)

#!/usr/bin/env python
# encoding: utf-8
'''
@Author  : 草木零
@Software: PyCharm
@File    : test_usefixtures.py
@Time    : 2023/8/22 19:12
@desc   : 使用装饰器@pytest.mark.usefixtures()修饰需要运行的用例
'''
import pytest@pytest.fixture
def fix1():print('fixture1的打印值')@pytest.fixture
def fix2():print('fixture2的打印值')# 函数使用usefixtures
@pytest.mark.usefixtures('fix1','fix2')
def test_func():print('函数usefixtures的使用方法')# class使用fixtures
# 这种直接在类上统一的使用fixtrue,类当中的用例就不用再重复使用了
@pytest.mark.usefixtures('fix1','fix2')
class Test_class01:def test_01(self):print('类Test_class01里的测试用例1')def test_02(self):print('类Test_class01里的测试用例2')# class使用fixtures
# 1.注意:这种方法,在fixture+conftest.py的组合形式下,是无法被引用的
# 2. 这种直接在类上统一的使用fix,类当中的用例就不用再重复使用了
# 如果一个方法或者一个class用例想要同时调用多个fixture,可以使用@pytest.mark.usefixtures()进行叠加。
# 注意叠加顺序,先执行的放底层,后执行的放上层。
# 比如这里,fix2放在下层,所以先调fix2
@pytest.mark.usefixtures('fix1')
@pytest.mark.usefixtures('fix2')
class Test_class02:def test_01(self):print('类Test_class02里的测试用例1')def test_02(self):print('类Test_class02里的测试用例2')if __name__ == '__main__':pytest.main(['-s', 'test_usefixtures.py'])

控制台输出:
在这里插入图片描述

五、类使用fixture的两种方式

装饰器@pytest.mark.usefixtures()

例子见上面四

通过类属性引用 fixture:pytest.lazy_fixture()

若fixture返回数据且测试类需要使用

@pytest.fixture
def user_data():return {"name": "Alice", "age": 30}# 方法一:通过测试方法的参数获取
# class TestUser:
#     def test_user_age(self, user_data):  # 方法参数获取返回值
#         assert user_data["age"] == 30# 方法二:通过 pytest.lazy_fixture(推荐)
class TestUser:# 声明类级别的 fixture 依赖,并可在方法中使用user_data = pytest.lazy_fixture("user_data")def test_user_age(self):assert self.user_data["age"] == 30  # 通过 self 访问 fixture 返回值

六、函数/方法使用多个fixture

执行顺序由装饰器或参数列表的顺序决定

#!/usr/bin/env python
# encoding: utf-8
'''
@Author  : 草木零
@Software: PyCharm
@File    : test_multiFixtures.py
@Time    : 2023/8/22 20:11
@desc   : 使用多个fixture
'''
import pytest
@pytest.fixture
def fix1():return ('葡萄', '芒果')@pytest.fixture
def fix2():print('这是fix2')def test_multiFix(fix1, fix2):print(fix1[0], fix1[1])if __name__ == '__main__':pytest.main(['-s', 'test_multiFixtures.py'])

控制台
在这里插入图片描述

注意上面的输出,先输出fix2的内容,尽管顺序是(fix1, fix2)

输出顺序由 pytest 的 fixture 初始化算法决定:

  • 无依赖的 fixture 按参数列表顺序初始化(通常情况)
  • 有副作用(如打印)的 fixture 会提前暴露执行痕迹

最佳实践:

  • 避免在 fixture 中使用有副作用的操作(如打印)
  • 通过显式依赖链(fixture 依赖其他 fixture)控制顺序
  • 使用 pytest-ordering 插件精确控制测试执行顺序

执行顺序与参数位置无关:

  • 参数列表中的顺序不保证 fixture 实际执行顺序
  • pytest 会优化依赖图以最小化初始化开销

使用fixture的方式选择

两种方式的选择取决于是否需要获取 fixture 的返回值:

  • @pytest.mark.usefixtures:适合 “执行后无需结果” 的场景(如环境初始化)。
  • test_case(fix):适合 “需要使用 fixture 数据” 的场景(如提供测试参数)。
import pytest
@pytest.fixture(params=[1, 2])
def numbers(request):return request.param# 方式1:通过装饰器
@pytest.mark.usefixtures("numbers")
def test_with_decorator():# 无法直接访问 numbers 的值,但测试会执行两次(参数为 1 和 2)pass# 方式2:通过参数
def test_with_param(numbers):assert numbers in [1, 2]  # 可直接使用参数值if __name__ == '__main__':pytest.main(['-sv', 'test_fixture_contrast.py'])

控制台输出:
在这里插入图片描述

七、fixture之params参数化

@pytest.fixture(params=list) ,params参数接收列表类型数据,fixture函的 params 请求参数数量决定fixture函数执行的次数。

request.param:request是pytest的内置fixture,主要用于传递参数

#!/usr/bin/env python
# encoding: utf-8
'''
@Author  : 草木零
@Software: PyCharm
@File    : test_fixture_params.py
@Time    : 2023/8/22 23:58
@desc   : fixture之params参数化,@pytest.fixture(params=list)    #params参数接收列表类型数据
'''
import pytest
def read_list():return ['芒果', '榴莲', '樱桃']
@pytest.fixture(params=read_list())  # params参数接收列表类型数据
def fix(request):# request是pytest的内置fixture,主要用于传递参数print(request.param, type(request.param))fruit = request.paramreturn fruit
def test_params(fix):print('params接收的列表有多少个元素,本用例就执行多少次,这次接收的水果是{}'.format(fix))
if __name__ == '__main__':pytest.main(['-s', 'test_fixture_params.py'])

控制台输出:
在这里插入图片描述

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

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

相关文章

Unity知识点-Renderer常用材质变量

本篇总结了Unity中renderer的3种常用的材质相关的变量:renderer.material,renderer.sharedMaterial,renderer.MaterialPropertyBlock。以及三者对SRPBatcher的影响。 一.介绍及对比 1.概念介绍 1.material 定义:material 是Render组件(如…

【算法】​​如何判断时间复杂度?

文章目录 1. 什么是时间复杂度?为什么需要时间复杂度? 2. 常见时间复杂度对比3. 如何分析时间复杂度?(Java版)🔹 步骤1:找出基本操作🔹 步骤2:分析循环结构(1…

MySQL使用C语言连接

文章目录 版本查看以及编译mysql接口介绍初始化链接数据库下发mysql命令mysql_query获取执行结果mysql_store_result获取结果行数mysql_num_rows获取结果列数mysql_num_fields获取列名mysql_fetch_fields获取结果内容mysql_fetch_row关闭mysql链接mysql_closeC语言操作mysql查看…

坚持每日Codeforces三题挑战:Day 7 - 题目详解(2025-06-11,难度:1200,1300,1500)

每天坚持写三道题第七天: Problem - A - Codeforces 1200 Problem - B - Codeforces 1300 Problem - A - Codeforces 1500 目录 题目一: 题目大意: 解题思路: 代码(C): 题目二: 题目大意: 解题思路: 代码(C): 题目三: 题目大意: 解题思路: 代码(C): …

洛谷 P4305:[JLOI2011] 不重复数字 ← unordered_set

【题目来源】 https://www.luogu.com.cn/problem/P4305 【题目描述】 给定 n 个数,要求把其中重复的去掉,只保留第一次出现的数。 【输入格式】 第一行一个整数 T,表示数据组数。 对于每组数据,第一行一个整数 n。第二行 n 个数…

STM32固件升级设计——SPIFLASH模拟U盘升级固件

目录 概述 一、功能描述 1、BootLoader部分: 2、APP部分: 二、BootLoader程序制作 1、分区定义 2、 主函数 3、配置USB 4、配置fatfs文件系统 5、程序跳转 三、APP程序制作 四、工程配置(默认KEIL5) 五、运行测试 六…

解锁阿里云日志服务SLS:云时代的日志管理利器

引言:开启日志管理新篇 在云计算时代,数据如同企业的血液,源源不断地产生并流动。从用户的每一次点击,到系统后台的每一个操作,数据都在记录着企业运营的轨迹。而在这些海量的数据中,日志数据占据着至关重…

Keye-VL-8B-Preview:由快手 Kwai Keye 团队精心打造的尖端多模态大语言模型

🔥 News 2025.06.26 🌟 我们非常自豪地推出Kwai Keye-VL,这是快手Kwai Keye团队精心打造的前沿多模态大语言模型。作为快手先进技术生态中的核心AI产品,Keye在视频理解、视觉感知和推理任务方面表现卓越,树立了新的性…

Web前端之JavaScript实现图片圆环、圆环元素根据角度指向圆心、translate、rotate

MENU 前言效果HtmlStyleJavaScript 前言 代码段创建了一个由6个WiFi图标组成的圆形排列&#xff0c;每个图标均匀分布在圆周上。 效果 Html 代码 <div class"ring"><div class"item"><img class"img" src"../image/icon/W…

1 Studying《Computer Vision: Algorithms and Applications 2nd Edition》11-15

目录 Chapter 11 Structure from motion and SLAM 11.1 几何内禀校准 11.2 姿态估计 11.3 从运动中获得的双帧结构 11.4 从运动中提取多帧结构 11.5 同步定位与建图&#xff08;SLAM&#xff09; 11.6 额外阅读 Chapter 12 Depth estimation 12.1 极点几何 12.2 稀疏…

phpstudy 可以按照mysql 数据库

phpstudy 可以按照mysql 数据库 PHPStudy&#xff08;小皮面板&#xff09;是一款专为开发者设计的集成环境工具&#xff0c;涵盖服务器配置、开发环境搭建、网站部署等多项功能。以下是其核心用途及优势的详细解析&#xff1a; 一、开发环境快速搭建 一站式集成环境集成Apa…

Python搭建HTTP服务,如何用内网穿透快速远程访问?

Python的内置HTTP服务模块是开发者工具箱中的瑞士军刀&#xff0c;只需一行命令即可启动一个功能完备的Web服务器。无论是前端工程师调试页面、数据科学家共享Jupyter Notebook&#xff0c;还是后端开发者快速验证API原型&#xff0c;Python HTTP服务都能以零配置的方式满足需求…

拨号音识别系统的设计与实现

拨号音识别系统的设计与实现 摘要 本文设计并实现了一个完整的拨号音识别系统&#xff0c;该系统能够自动识别电话号码中的数字。系统基于双音多频(DTMF)技术原理&#xff0c;使用MATLAB开发&#xff0c;包含GUI界面展示处理过程和结果。系统支持从麦克风实时录音或加载音频文…

数据结构-树详解

树简介 树存储和组织具有层级结构的数据&#xff08;例&#xff1a;公司职级&#xff09;&#xff0c;就是一颗倒立生长的树。 属性&#xff1a; 递归n个节点有n-1个连接节点x的深度&#xff1a;节点x到根节点的最长路径节点x的高度&#xff1a;节点x到叶子节点的最长路径 …

【安卓Sensor框架-2】应用注册Sensor 流程

注册传感器的核心流程为如下&#xff1a;应用层调用 SensorManager注册传感器&#xff0c;framework层创建SensorEventQueue对象&#xff08;事件队列&#xff09;&#xff0c;通过JNI调用Native方法nativeEnableSensor()&#xff1b;SensorService服务端createEventQueue()创建…

新版本没有docker-desktop-data分发 | docker desktop 镜像迁移

在新版本的docker desktop中&#xff08;如4.42版本&#xff09;&#xff0c;镜像迁移只需要更改路径即可。如下&#xff1a; 打开docker desktop的设置&#xff08;图1&#xff09;&#xff0c;将图2的原来的地址C:\Users\用户\AppData\Local\Docker\wsl修改为你想要的空文件…

EtherCAT SOEM源码分析 - ec_init

ec_init SOEM主站一切开始的地方始于ec_init, 它是EtherCAT主站初始化的入口。初始化SOEM 主站&#xff0c;并绑定到socket到ifname。 /** Initialise lib in single NIC mode* param[in] ifname Dev name, f.e. "eth0"* return >0 if OK* see ecx_init*/ in…

84、原理解析-SpringApplication创建初始化流程

84、原理解析-SpringApplication初始化流程 # SpringApplication创建初始化流程原理解析 SpringApplication的创建和初始化是Spring Boot应用启动的关键步骤&#xff0c;主要包括以下过程&#xff1a; ## 1. 创建SpringApplication实例 ### 1.1 调用构造函数 - 当调用SpringApp…

【数理逻辑】 选择公理与集值映射

目录 选择公理1. 有限指标集 I I I2. 可数无限指标集 I I I &#xff08;简称为 ACC 或 ACω&#xff09;3. 不可数无限指标集 I I I4. 选择公理的层级与数学应用5. 选择公理的深层意义 集值映射的选择函数1. 选择公理的核心作用2. 不同情况下的依赖性分析3. AC 的必要性证明…

微信小程序使用wx.chooseImage上传图片时进行压缩,并添加时间水印

在微信小程序的开发过程&#xff0c;经常会使用自带的api(wx.chooseImage)进行图片拍照或选择图片进行上传&#xff0c;有时图片太大&#xff0c;造成上传和下载时过慢&#xff0c;现对图片进行压缩后上传&#xff0c;以下是流程和代码 一、小程序的版本选择了3.2.5&#xff0…