Pytest框架中fixture功能详解

文章目录

1 定义 Fixture函数

2 Fixture 的函数参数

2.1 传入其他fixture函数作为参数

2.2 传入request对象参数

示例1:访问fixture的调用者

示例2:使用fixture的参数

3 Fixture 的作用域参数scope

3.1 scope=class场景

3.2 scope=session场景

4 Fixture 的自动使用参数autouse=True

5 Fixture 的参数化params和ids

6 fixture函数传入的request到底是啥?

pytest 的 fixture 是一个非常强大的功能,它允许你在测试函数或测试类之间共享设置和清理代码。fixture可以被看作是测试中的“依赖注入”机制,它允许你以函数的形式定义这些依赖,并在需要时将其注入到测试函数中。

pytest官方文档是这样解释的:
https://docs.pytest.org/en/latest/how-to/fixtures.html#how-to-fixtures

由于英语不好,只能百度翻译如下:

在测试中,fixtures(夹具)为测试提供了一个定义明确、可靠且一致的上下文。这个上下文可以包括环境(例如配置有已知参数的数据库)或内容(如数据集)。

Fixtures 定义了测试的 "arrange"(安排)阶段所需的步骤和数据。在 pytest 中,fixtures 是你定义的函数,用于这个目的。它们也可以用于定义测试的 "act"(行动)阶段,这是设计更复杂测试的一个强大技巧。

由 fixtures 设置的服务、状态或其他操作环境通过参数被测试函数访问。对于测试函数使用的每个 fixture,通常在测试函数的定义中有一个以 fixture 命名的参数。

我们可以通过 @pytest.fixture 装饰器来告诉 pytest 某个函数是一个 fixture。

我们举个简单的例子理解下:

定义一个用 @pytest.fixture 装饰的函数fixture_steup_exec,

并将函数fixture_steup_exec作为参数传入测试用例test_1中。

@pytest.fixture
def fixture_steup_exec():print('\n执行测试用例前,先执行我这个fixture函数')def test_1(fixture_steup_exec):assert 1==1print('\n用例test_1执行成功'

当我们执行测试用例test_1时,程序发现参数fixture_steup_exec正是被 @pytest.fixture装饰的函数,那么先执行被装饰函数中的代码,然后才执行测试用例的代码。

test_1的执行结果如下:

1 定义 Fixture

使用 @pytest.fixture 装饰器来定义一个 fixture。

主要有几个参数fixture_function,scope,params,autouse,ids等,下面几个章节会详细介绍。

被@pytest.fixture 装饰的函数会在测试函数或测试方法之前运行,并返回一个值,该值可以作为参数传递给测试函数或测试方法。

举例:定义my_fixture函数返回data,将该函数传入测试用例test_example。

@pytest.fixture
def my_fixture():#这里是设置代码 data = "Hello, pytest!"return data
def test_example(my_fixture):assert my_fixture=="Hello, pytest!"print(f"\nmy_fixture 返回的值: {my_fixture}")

用例执行结果:

2 Fixture 的fixture_function参数

1)Fixture 函数可以接受其他 fixture 作为参数。换句话说定义的fixture 可以依赖于其他 fixture 来执行设置和清理工作。

2)Fixture 函数还可以接受 request 对象作为参数,这个对象提供了关于当前请求的额外信息,如 fixture 的名称、参数等。

2.1 传入其他fixture函数作为参数

一个 fixture 可以依赖于另一个 fixture,只需将依赖的 fixture 作为参数传递给 fixture 函数即可。

举例:定义fixture_a,同时定义fixture_b,参数传入fixture_a。

@pytest.fixture
def fixture_a():return "a"@pytest.fixture
def fixture_b(fixture_a): # 依赖于 fixture_areturn fixture_a + "b"def test_both_fixtures(fixture_b):assert fixture_b == "ab"print('\n调用了fixture_b 和 fixture_a')

将fixture_b作为参数传入测试用例test_both_fixtures,执行成功。

2.2 传入request对象参数

request是pytest中fixture函数的一个特殊参数,它提供了许多有关当前测试请求的信息。request对象主要有以下功能:

1)访问fixture的调用者:我们可以知道是哪个测试或fixture调用了当前的fixture。

2)获取fixture的参数:如果fixture有参数可以使用request.param来访问这些参数。

3)访问fixture的上下文:request对象还提供了许多其他方法和属性,允许你更深入地了解当前测试请求的上下文。

以下是一些使用request的示例:

示例1:访问fixture的调用者

通过在fixture函数传入request,通过request.node.name获取测试用例名称。

@pytest.fixture
def my_parametrized_fixture(request):print(f'是那个测试用例调用了我: {request.node.name}')def test_case1(my_parametrized_fixture):print(f"Running testcase1")

示例2:使用fixture的参数

举例:传入两个参数value1和value2,并打印下测试用例获取的fixture的参数值。

@pytest.fixture(params=["value1", "value2"])
def example_fixture(request):return request.paramdef test_example(example_fixture):print(f"Using value: {example_fixture}")

用例执行结果:

3 Fixture 的作用域参数scope

默认情况下,fixture 的作用域是函数级,可通过 scope 参数来改变 fixture 的作用域。可用的作用域有:["session", "package", "module", "class", "function"]

scope 参数解释:

  • function(默认)

每个测试函数都会执行一次 fixture。

适用于每个测试用例都需要独立设置和清理资源的场景。

  • class

每个测试类都会执行一次 fixture。

在类中定义的第一个测试方法执行前执行 fixture,在类中的所有测试方法执行后执行 teardown(如果使用了 yield)。

适用于类中的多个测试方法共享相同设置和清理资源的场景。

  • module

一个 Python 模块(一个 .py 文件)只会执行一次 fixture。

在模块中的第一个测试函数或方法执行前执行 fixture,在模块中的所有测试函数或方法执行后执行 teardown(如果使用了 yield)。

适用于整个模块内的多个测试函数或方法共享相同设置和清理资源的场景。

  • session

整个测试会话期间只执行一次 fixture。

在 pytest 会话开始时执行 fixture,在所有测试文件执行完毕后执行 teardown(如果使用了 yield)。

适用于整个测试套件需要共享的设置和清理资源的场景,如数据库连接、浏览器驱动等。

当 fixture 设置为 autouse=True 时,结合 scope 参数,fixture 将在指定的作用域内自动生效,无需在每个测试函数或类中显式引用。

3.1 scope=class场景

举例:在测试类执行前执行setup和teardown的动作。

定义一个fixture函数,在该函数使用 @pytest.fixture(scope='class') 装饰器(应用于类时scope参数定义为class),并使用yield关键字,yield上面的代码在类中第一个测试用例执行前执行,yield下面的代码在类中最后一条用例执行后执行。我们将这个fixture 作为类中测试方法的参数,以此来实现类中的setup和teardown功能。

@pytest.fixture(scope='class')
def class_setup_teardown():print("\nClass setup (equal to setup_class)")# 设置代码yieldprint("\nClass teardown (equal to teardown_class)")# 清理代码
第一种方式:在测试函数中传入定义的fixture函数作为参数
class Testcase:def test_one(self, class_setup_teardown): # 直接将fixture作为参数print("\nRunning test_one")# 测试代码def test_two(self, class_setup_teardown): # 同样地,直接作为参数print("\nRunning test_two")# 测试代码
  • 第二种方式:在测试类中注明使用fixture,测试函数中不传参数
@pytest.mark.usefixtures("class_setup_teardown")
class Testcase: def test_one(self): print("\nRunning test_one")# 测试代码def test_two(self):print("\nRunning test_two")# 测试代码

用例执行后结果如下:两种方式都实现了测试类setup和teardown的功能

3.2 scope=session场景

由于 session 级别的 fixture 在整个测试会话中只执行一次,因此它可以跨多个测试文件共享资源(而module级别的只能在单个py文件内适用)。

举例:我们有一个需要连接数据库的 fixture,并且这个连接在整个测试会话期间只需要建立一次。

@pytest.fixture(scope='session')
def db_connection_fixture():# 这里是建立数据库连接的代码print("Connecting to database...")yield # 暂停点,测试函数开始执行# 这里是关闭数据库连接的代码print("Closing database connection...")# 之后的测试函数或类将自动使用这个 fixture,无需显式引用def test_database_operation(db_connection_fixture):# 在这里执行数据库操作,db_connection fixture 已经在会话开始时自动建立连接pass

由于 scope="session" ,db_connection fixture 将在整个测试会话开始时自动建立数据库连接,并在所有测试执行完毕后自动关闭连接。

4 Fixture 的自动使用参数autouse=True

autouse=True 参数使 fixture 在所有测试函数或测试类中自动使用,而无需将其作为参数传递。但这可能会导致代码更难理解和维护。

举例:上面我们创建的scope=class的fixture函数,如果加上参数autouse=True,则不需要在测试类中在使用这个fixture函数。

@pytest.fixture(scope='session', autouse=True)
def class_setup_teardown():print("\nClass setup (equal to setup_class)")# 设置代码yieldprint("\nClass teardown (equal to teardown_class)")# 清理代码#@pytest.mark.usefixtures("class_setup_teardown")
#完全可以注释该fixture函数的使用
class Testcase2:def test_one(self):print("\nRunning test_one")# 测试代码def test_two(self):print("\nRunning test_two")# 测试代码

5 Fixture 的参数化params和ids

允许为fixture指定多个参数值,并为每个参数值运行测试函数。通常params与ids参数结合使用,ids为参数化值提供别名,在后续测试报告中更容易识别每个参数化测试。

举例:给fixture传入三个参数和它们的ids,执行测试用例后,其实会执行3个用例。

@pytest.fixture(params=[1, 2, 3],ids=['id1','id2','id3'])
def my_parametrized_fixture(request):return request.paramdef test_parametrized_fixture(my_parametrized_fixture):print(f"Running test with {my_parametrized_fixture}")

执行后结果如下:

6 fixture函数传入的request到底是啥?

request 参数,对应访问的是特殊的 FixtureRequest 对象,它提供了关于当前请求的上下文信息。

以下是位于pytest.fixture文件中的FixtureRequest 类:

在初始化函数中添加了一行打印,如上图所示。

FixtureRequest 对象包含以下一些有用的属性和方法:

属性

1)fixturename: 当前 fixture 的名称。

2)param: 如果 fixture 被参数化,则这是当前参数的值。

3)scope: fixture 的作用域(例如 "function", "class", "module", "session")。

4) config: pytest 的配置对象。

5) session: pytest 的 session 对象。

6)node: 收集到的节点(通常是测试用例或类)。

7)function: 如果 fixture 被一个测试函数调用,则这是该函数。

8)cls: 如果 fixture 被一个测试类使用,则这是该类。

9)instance: 如果 fixture 被一个测试类的实例方法使用,则这是该实例。

10)module: 如果 fixture 被一个模块中的测试使用,则这是该模块。

11)fspath: 调用 fixture 的文件路径。

方法

1)addfinalizer(finalizer): 添加一个将在测试结束后调用的 finalizer 函数。这可以用于执行清理操作。

2)getfixturevalue(argname): 请求另一个 fixture 的值。

3)getparam(name, default): 检索参数的当前值,如果该参数未定义则返回默认值。

举例:在测试用例中打印下部分request的属性:

@pytest.fixture(params=["value1", "value2"])
def example_fixture(request):return requestdef test_example(example_fixture):print(f"\nrequest.fspath : {example_fixture.fspath}")print(f"\nrequest.node : {example_fixture.node}")print(f"\nrequest.scope : {example_fixture.scope}")print(f"\nrequest.fixturename : {example_fixture.fixturename}")print(f"\nrequest.module : {example_fixture.module}")print(f"\nrequest.config : {example_fixture.config}")

用例执行后结果:打印了上面自己添加的一行记录,说明调用了FixtureRequest 。

共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”

-----指水滴不断地滴,可以滴穿石头;

-----比喻坚持不懈,集细微的力量也能成就难能的功劳。

----感谢读者的阅读和学习,点个赞和关注吧,谢谢大家。

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

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

相关文章

SwiftUI 6.0(iOS 18)新容器视图修改器漫谈

概览 本届 WWDC 2024 观影正如火如荼的进行中,一片鸟语花香、枝繁叶茂的苹果树上不时结出几颗令人垂涎欲滴的美味苹果让秃头码农们欲罢不能。 如您所愿,在界面布局“利器” SwiftUI 这根蔓藤也长出不少喜人的果实,其中在 iOS 18.0 中新添加的…

rabbitMQ的简单使用

rabbitMQ的介绍 RabbitMQ是一个开源的消息代理和队列服务器,主要用于在不同的应用程序之间传递消息。它基于AMQP(Advanced Message Queuing Protocol)协议,提供了一种可靠的方式来处理异步通信。RabbitMQ使用Erlang语言编写&…

springboot 整合redis问题,缓存击穿,穿透,雪崩,分布式锁

boot整合redis 压力测试出现失败 解决方案 排除lettuce 使用jedis <!-- 引入redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclus…

内存泄漏 内存溢出

概念 内存泄漏&#xff1a;是程序没有正确的释放已分配的内存&#xff0c;造成系统内存的浪费。内存泄漏很难发现&#xff0c;因为他不会直接导致程序崩溃&#xff0c;而是会慢慢降低程序的性能。 内存溢出&#xff1a;系统中存在无法回收的内存或使用的内存过多&#xff0c;…

【linux-imx6ull-定时器与中断】

目录 1. 前言2. Linux软件定时器2.1 内核频率选择2.2 重要的API函数2.3 Linux软件定时器的使用配置流程 4. Linux中断4.1 简单中断使用4.1.1 简要说明4.1.2 重要的API函数4.1.3 中断的简要配置流程 4.2. 中断的上半部和下半部4.2.1 tasklet实现下半部4.2.2 work实现下半部 1. 前…

MySQL数据操作与查询- 聚合函数和分组查询

一、聚合函数 聚合函数主要用来进行数据 汇总 。 1、sum 返回选取的某列的总和。 语法&#xff1a; select sum(字段名) from 表名 where 条件表达式 2、max 返回选取的某列的最大值。 语法&#xff1a; select max(字段名) from 表名 where 条件表达式 3、min 返…

【网络安全的神秘世界】AppScan安装及使用指南

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 https://www.hcl-software.com/appscan AppScan是一种综合型漏洞扫描工具&#xff0c;采用SaaS解决方案&#xff0c;它将所以测试功能整合到一个服务中&a…

样式的双向绑定的2种方式,实现样式交互效果

与样式标签实现双向绑定 通过布尔值来决定样式是出现还是消失 show代表着布尔值&#xff0c;show的初始值是false所以文本不会有高亮的效果&#xff0c;当用户点击了按钮&#xff0c;就会调用shows这个函数&#xff0c;并将show的相反值true赋值并覆盖给show,此时show的值为tru…

【秋招突围】2024届秋招笔试-小红书笔试题-第二套-三语言题解(Java/Cpp/Python)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系计划跟新各公司春秋招的笔试题 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f4e7; 清隆这边…

诊断解决方案——CANdesc和MICROSAR

文章目录 一、CANdesc二、MICROSAR一、CANdesc canbeded是Vector汽车电子开发软件Nun Autosar标准的工具链之一。 canbeded是以源代码的形式提供的可重用的组件,包括CAN Driver,交互层(IL),网络管理(NM),传输层(TP),诊断层(CANdesc) , 通信测量和标定协议(CCP,XCP) 和 通信控…

404 页面代码

<template> <div class"container"><h1>404</h1> <div ><p class"text-center">当前页面无法访问,可能没有权限或已删除</p><p class"text-center"> 去别处看看吧</p> </div> <…

Internet Download Manager(IDM6.41)软件安装包下载及安装教程

Internet Download Manager有一个智能下载逻辑加速器&#xff0c;具有智能动态文件分割和安全的多部分下载技术&#xff0c;可以加速下载。与其他下载加速器和管理器不同&#xff0c;Internet下载管理器在下载开始之前对文件进行分段&#xff0c;而Internet下载管理器在下载过程…

[Linux] TCP协议介绍(2): TCP协议的“三次握手“过程分析、超时重传机制介绍...

上一篇文章中, 已经介绍了TCP协议的数据格式, 简单分析了其与UDP协议 关于可靠性方面的差异 本篇文章, 介绍分析一下 使用TCP协议通信, 非常重要的一个过程: 三次握手 TCP的"三次握手" TCP协议是有连接的传输层协议, 即使用TCP协议通信, 是需要建立连接的 TCP协议…

JVM-基础知识

JVM-基础知识 什么是JVM JVM是一种跨语言的平台&#xff0c;任何语言只要能编译成.class文件都可以被JVM运行。JVM只和.class文件有关系&#xff0c;和Java语言没关系。JVM是一种虚拟机规范。 java文件是如何交给JVM执行的 JVM的常见实现 HostStop:Oracle官方另外还有IBM的J9、…

Java--Arrays类

1.数组的工具java.util.Arrays 2.由于数组对象本身并没有什么方法可以供我们调用&#xff0c;但API中提供了一个工具类Arrays供我们使用&#xff0c;从而可以对数据对象进行一些基本的操作。 3.查看JDK帮助文档 4.Arrays类中的方法都是static修饰静态的静态方法&…

MyBatis操作数据库(一)

什么是MyBatis? MyBatis是一个优秀的持久层框架&#xff0c;⽤于简化JDBC的开发。 MyBatis本是Apache的⼀个开源项⽬iBatis&#xff0c;2010年这个项目由apache迁移到了googlecode&#xff0c;并且改名为MyBatis。 简单来说MyBatis是更加简单完成数据和数据库交互的框架 什么…

2-6 基于matlab2018B的语音信号降噪和盲源分离GUI界面

基于matlab2018B的语音信号降噪和盲源分离GUI界面&#xff0c;包括维纳滤波&#xff0c;小波降噪、高通、低通、带通滤波&#xff0c;及提出的滤波方法。每个功能均展示降噪前后声音效果并外放出来。程序已调通&#xff0c;可直接运行。 2-6 语音信号降噪 盲源分离 GUI界面 - 小…

canvas学习

Canvas API 提供了一个通过 JavaScript 和 HTML 的 元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。 Canvas 的基本用法 <canvas> 元素 <canvas id"tutorial" width"150" height"150&quo…

[Python]Anaconda相关命令

环境操作相关命令 查看所有环境 conda env list创建环境 conda create --name cahttts python3.10激活环境 conda activate cahttts安装依赖文件 pip install -r requirements.txt查看GPU型号 nvidia-smi -LGPU 0: NVIDIA A10 (UUID: GPU-9f1fc9cf-582a-25ac-849c-2f77343…

ESD与EOS区别

最近小白在做项目时&#xff0c;被一个实习生问道了&#xff0c;关于EOS与ESD区别。说实话&#xff0c;以前专注于测试debug的我&#xff0c;在回答对方时&#xff0c;并没法做到太全面的解答。于是乎&#xff0c;借助周内的空闲时间&#xff0c;小白还是简单学习总结了一番。 …