Pytest 高级用法:间接参数化
文章目录
- 1. 引言
- 2. 基础概念
- 2.1 Fixture
- 2.2 参数化
- 3. 代码实例
- 3.1 基础设置
- 3.2 测试用例示例
- 示例 1:基础的间接参数化
- 示例 2:通过 request 获取参数值
- 示例 3:多参数组合测试
- 示例 4:部分间接参数化
- 4. 最佳实践
- 5. 总结
- 参考资料
1. 引言
在进行单元测试时,我们经常需要使用不同的参数来测试同一个功能。Pytest 提供了强大的参数化功能,并且可以与 fixture 结合使用,使得测试代码更加灵活和可维护。本文将深入探讨 pytest 中参数化和 fixture 的高级用法。
2. 基础概念
2.1 Fixture
Fixture 是 pytest 中的一个核心概念,它提供了一种方式来为测试提供可复用的依赖。Fixture 可以:
- 提供测试数据
- 设置测试环境
- 处理测试资源的创建和清理
2.2 参数化
参数化允许我们使用不同的参数多次运行同一个测试。pytest 提供了两种主要的参数化方式:
- 直接参数化:参数直接传递给测试函数
- 间接参数化:参数通过 fixture 传递给测试函数
3. 代码实例
3.1 基础设置
首先,我们需要创建两个文件:conftest.py
和 test_fixture_indirect.py
。
# conftest.py
import pytest@pytest.fixture(scope='module')
def fixture_indirect(request):print(f"fixture_indirect, request: {request}")print(f"fixture_indirect, request.param: {request.param}")var = 'var_from_fixture_indirect'yield var@pytest.fixture(scope='module')
def fixture_direct(request): # request 参数可选print(f"fixture_direct, request: {request}")var = 'var_from_fixture_direct'yield var
3.2 测试用例示例
示例 1:基础的间接参数化
- 使用
indirect=True
表示参数会传递给同名的 fixture - fixture 会接收到参数值,但测试函数只能获得 fixture 的返回值
@pytest.mark.parametrize("fixture_indirect", [110, 120], indirect=True)
def test_fixture_indirect(fixture_indirect):print(f"Case fixture_indirect: {fixture_indirect}")# 注意:这里无法直接访问参数值 110, 120"""
会运行两次测试,每次:
- 先执行 fixture_indirect,获得参数 110/120
- 然后运行测试函数,得到 fixture 的返回值
"""
fixture_indirect, request: <SubRequest 'fixture_indirect' for <Function test_fixture_indirect[110]>>
fixture_indirect, request.param: 110
PASSED [ 50%]
Case fixture_indirect: var_from_fixture_indirectfixture_indirect, request: <SubRequest 'fixture_indirect' for <Function test_fixture_indirect[120]>>
fixture_indirect, request.param: 120
PASSED [100%]
Case fixture_indirect: var_from_fixture_indirect
示例 2:通过 request 获取参数值
- 通过 request 参数获取原始的参数化值
- 使用
request.node.callspec.params
访问参数字典
@pytest.mark.parametrize("fixture_indirect", [110, 120], indirect=True)
def test_fixture_indirect_request(fixture_indirect, request):print(f"Case fixture_indirect: {fixture_indirect}")my_test_param = request.node.callspec.params['fixture_indirect']print(f"Case request.param: {my_test_param}")"""
除了基本功能外,还能获取原始参数:
- fixture 的返回值: var_from_fixture_indirect
- 原始参数值: 110/120
"""
fixture_indirect, request: <SubRequest 'fixture_indirect' for <Function test_fixture_indirect_request[110]>>
fixture_indirect, request.param: 110
PASSED [ 50%]
Case fixture_indirect: var_from_fixture_indirect
Case request.param: 110fixture_indirect, request: <SubRequest 'fixture_indirect' for <Function test_fixture_indirect_request[120]>>
fixture_indirect, request.param: 120
PASSED [100%]
Case fixture_indirect: var_from_fixture_indirect
Case request.param: 120
示例 3:多参数组合测试
- 如何组合多个参数化装饰器
- 直接参数化和间接参数化的混合使用
@pytest.mark.parametrize("fixture_indirect", [111, 222], indirect=True)
@pytest.mark.parametrize("test_param", ['a', 'b'])
def test_fixture_param(fixture_indirect, test_param):print(f"fixture_indirect: {fixture_indirect}")print(f"test_param: {test_param}")"""
会生成 4 个测试用例组合:
(111, 'a')
(111, 'b')
(222, 'a')
(222, 'b')
"""
fixture_indirect, request: <SubRequest 'fixture_indirect' for <Function test_fixture_param[a-111]>>
fixture_indirect, request.param: 111
PASSED [ 25%]
Case fixture_indirect: var_from_fixture_indirect
Case test_param: a
PASSED [ 50%]
Case fixture_indirect: var_from_fixture_indirect
Case test_param: bfixture_indirect, request: <SubRequest 'fixture_indirect' for <Function test_fixture_param[a-222]>>
fixture_indirect, request.param: 222
PASSED [ 75%]
Case fixture_indirect: var_from_fixture_indirect
Case test_param: a
PASSED [100%]
Case fixture_indirect: var_from_fixture_indirect
Case test_param: b
示例 4:部分间接参数化
- 如何在一个参数化中同时使用直接和间接参数
- 使用
indirect
列表指定哪些参数是间接的
@pytest.mark.parametrize("fixture_indirect, my_test_param",[(111, 'a'), (222, 'b')],indirect=['fixture_indirect'])
def test_fixture_indirect_param_partial(fixture_indirect, my_test_param):print(f"Case fixture_indirect: {fixture_indirect}")print(f"Case test_param: {my_test_param}")"""
会生成 2 个测试用例:
(111, 'a')
(222, 'b')
"""
fixture_indirect, request: <SubRequest 'fixture_indirect' for <Function test_fixture_indirect_param_partial[111-a]>>
fixture_indirect, request.param: 111
PASSED [ 50%]
Case fixture_indirect: var_from_fixture_indirect
Case test_param: afixture_indirect, request: <SubRequest 'fixture_indirect' for <Function test_fixture_indirect_param_partial[222-b]>>
fixture_indirect, request.param: 222
PASSED [100%]
Case fixture_indirect: var_from_fixture_indirect
Case test_param: b
4. 最佳实践
-
选择合适的参数化方式
- 简单参数使用直接参数化
- 需要预处理或者复杂设置的参数使用间接参数化
-
合理使用 scope
- 对于耗时的 fixture,使用更大的 scope(如 module)可以提高测试效率
- 注意 scope 对测试隔离的影响
-
参数化组织建议
- 相关的参数组合放在一起
- 使用有意义的参数名
- 考虑测试的可读性和维护性
5. 总结
Pytest 的参数化和 fixture 功能为我们提供了强大而灵活的测试工具:
- 灵活性:可以根据需要选择直接或间接参数化
- 可复用性:fixture 机制支持测试代码的重用
- 可维护性:通过合理组织参数和 fixture,使测试代码更易维护
- 效率:支持多种方式组合参数,提高测试效率
掌握这些高级用法,可以帮助我们写出更好的测试代码,提高测试效率和代码质量。
参考资料
- Pytest 官方文档
- Pytest Fixture 文档
- Pytest Parametrize 文档
相关文章:
Pytest 高级用法:间接参数化
文章目录 1. 引言2. 基础概念2.1 Fixture2.2 参数化 3. 代码实例3.1 基础设置3.2 测试用例示例示例 1:基础的间接参数化示例 2:通过 request 获取参数值示例 3:多参数组合测试示例 4:部分间接参数化 4. 最佳实践5. 总结参考资料 1…...

第07章 存储管理(一)
一、磁盘简介 1.1 名称称呼 磁盘/硬盘/disk是同一个东西,不同于内存的是容量比较大。 1.2 类型 机械:机械硬盘即是传统普通硬盘,主要由:盘片,磁头,盘片转轴及控制电机,磁头控制器࿰…...
Go语言的 的设计模式(Design Patterns)核心知识
Go语言的设计模式(Design Patterns)核心知识 Go语言(Golang)是一种静态类型、编译型的编程语言,自2009年由Google正式推出以来,因其高效的性能、卓越的并发能力以及简洁的语法受到广泛欢迎。在软件开发中&…...

js函数预览图片:支持鼠标和手势拖拽缩放
对之前的方式改进:原生js实现图片预览控件,支持丝滑拖拽,滚轮放缩,放缩聚焦_js图片预览-CSDN博客 /*** 图片预览函数,调用后自动预览图片* param {图片地址} imgurl*/ function openImagePreview(imgurl) {if (!imgurl…...

用QT实现 端口扫描工具1
安装在线QT,尽量是完整地自己进行安装,不然会少包 参考【保姆级图文教程】QT下载、安装、入门、配置VS Qt环境-CSDN博客 临时存储空间不够。 Windows系统通常会使用C盘来存储临时文件。 修改临时文件存储位置 打开系统属性: 右键点击“此电…...

设计模式 结构型 适配器模式(Adapter Pattern)与 常见技术框架应用 解析
适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口,从而使原本因接口不兼容而无法一起工作的类能够协同工作。这种设计模式在软件开发中非常有用,尤其是在需要集成…...

vue 项目集成 electron 和 electron 打包及环境配置
vue electron 开发桌面端应用 安装 electron npm i electron -D记得加上-D,electron 需添加到devDependencies,如果添加到dependencies后面运行可能会报错 根目录创建electron文件夹,在electron文件夹创建main.js(或者backgrou…...

vscode如何离线安装插件
在没有网络的时候,如果要安装插件,就会麻烦一些,需要通过离线安装的方式进行。下面记录如何在vscode离线安装插件。 一、下载离线插件 在一台能联网的电脑中,下载好离线插件,拷贝到无法联网的电脑上。等待安装。 vscode插件商店地址:https://marketplace.visualstudio.co…...
计算机网络常见面试题及解答
以下是计算机网络中常见的面试题及解答,按主题分类: --- ## **一、基础概念** ### **1. OSI 七层模型和 TCP/IP 模型的区别是什么?** **答:** - **OSI 七层模型:** - 应用层、表示层、会话层、传输层、网络层、数…...
举例说明AI模型怎么聚类,最后神经网络怎么保存
举例说明怎么聚类,最后神经网络怎么保存 目录 举例说明怎么聚类,最后神经网络怎么保存K - Means聚类算法实现神经元特征聚类划分成不同专家的原理和过程 特征提取: 首先,需要从神经元中提取有代表性的特征。例如,对于一个多层感知机(MLP)中的神经元,其权重向量可以作为特…...

HarmonyOS NEXT应用开发实战(一):边学边玩,从零开发一款影视APP
引言 学习一项技能,最好也最快的办法就是动手实战。通过自己给自己找项目练习,不仅能够激发兴趣,还能从开发实战中不断总结经验。这种学习方法是最为高效的。今天,我们将通过开发一款名为“爱影家”的影视APP,来学习H…...

STM32G0B1 can Error_Handler 解决方法
问题现象 MCU上电,发送0x13帧数据固定进入 Error_Handler 硬件介绍 MCU :STM32G0B1 can:NSI1042 tx 接TX RX 接RX 折腾了一下午,无解,问题依旧; 对比测试 STM32G431 手头有块G431 官方评估版CAN 模块; 同样的…...
使用 `llama_index` 构建智能问答系统:多种文档切片方法的评估
使用 llama_index 构建智能问答系统:多种文档切片方法的评估 代码优化与解析1. **代码结构优化**2. **日志管理**3. **环境变量管理**4. **模型初始化**5. **提示模板更新**6. **问答函数优化**7. **索引构建与查询引擎**8. **节点解析器测试** 总结 在现代自然语言…...

【大模型】7 天 AI 大模型学习
7 天 AI 大模型学习 Day 2 今天是 7 天AI 大模型学习的第二天 😄,今天我将会学习 Transformer 、Encoder-based and Decoder-Based LLMs 等 。如果有感兴趣的,就和我一起开始吧 ~ 课程链接 :2025年快速吃透AI大模型&am…...
软件工程大复习之(四)——面向对象与UML
4.1 面向对象概述 面向对象(OO)是一种编程范式,它将数据和处理数据的方法封装在对象中。面向对象的主要概念包括: 对象:实例化的数据和方法的集合。类:对象的蓝图或模板。封装:隐藏对象的内部…...

【Linux】shell命令
目录 shell的基本命令 shell - 贝壳 外在保护工具 用户、shell、内核、硬件之间的关系 解析器的分类: shell命令格式 history -历史记录查询 修改环境变量的值: shell中的特殊字符 通配符 管道 | 输入输出重定向 命令置换符 shell的基本命…...

ValuesRAG:以检索增强情境学习强化文化对齐
随着大型语言模型(LLMs)的迅猛发展,其在各个领域展现出强大的能力。然而,训练数据中西方中心主义的倾向,使得 LLMs 在文化价值观一致性方面面临严峻挑战,这一问题在跨文化场景中尤为突出,可能导…...

【机器学习篇】交通革命:机器学习如何引领未来的道路创新
嘿,你知道吗?机器学习正在交通领域掀起一场革命啦!它将如何引领未来道路创新呢 本文有精彩的 C 代码演示、实用的图片解释,还有超多干货,保证让你大开眼界,点赞收藏关注, 开启一场奇妙的探索之…...

DeepSeek-V3 通俗详解:从诞生到优势,以及与 GPT-4o 的对比
1. DeepSeek 的前世今生 1.1 什么是 DeepSeek? DeepSeek 是一家专注于人工智能技术研发的公司,致力于打造高性能、低成本的 AI 模型。它的目标是让 AI 技术更加普惠,让更多人能够用上强大的 AI 工具。 1.2 DeepSeek-V3 的诞生 DeepSeek-V…...

把vue项目或者vue组件发布成npm包或者打包成lib库文件本地使用
将vue项目发布成npm库文件,第三方通过npm依赖安装使用;使用最近公司接了一个项目,这个项目需要集成到第三方页面,在第三方页面点击项目名称,页面变成我们的项目页面;要求以npm库文件提供给他们;…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...