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==1
  print('\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_a
  return 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.param

def 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)")
  # 设置代码
  yield
  print("\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)")
  # 设置代码
  yield
  print("\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.param

def 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 request

def 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.mfbz.cn/a/714550.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue52-scoped样式

一、scoped样式的作用 1-1、scoped样式的作用 vue中组件的样式都是汇总到一起的。容易出现一个问题:类名冲突。 示例: school和student组件的类名都叫demo,则student的样式将覆盖school的样式,因为App.vue中,先引入的…

光明网发稿投稿流程与要求,光明日报如何投稿?附光明网多少钱(价格表)

对于想要在光明网发稿的作者来说,媒介多多网发稿平台是一个绝佳的投稿选择。光明网作为国内一流的新闻媒体平台,其严谨的文章审核标准和广泛的读者基础吸引着无数作者。然而,由于其严格的发稿标准,一些作者可能会遇到一些困难&…

昂科烧录器支持Prolific旺玖科技的电力监控芯片PL7413C1FIG

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表,其中Prolific旺玖科技的高度集成的电力监控芯片PL7413C1FIG已经被昂科的通用烧录平台AP8000所支持。 PL7413C1FIG是一款高度集成的电力监控芯片,用于测量电力使用情况的…

springboot集成shardingsphere

导入maven依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spr…

知识图谱存在的挑战---隐私、安全和伦理相关和测试认证相关

文章目录 隐私、安全和伦理相关测试认证相关 隐私、安全和伦理相关 从部署拓扑结构而言&#xff0c;知识图谱技术以数据为核心、数据库为载体的方式来存储&#xff0c;有单机、云平台、集群及其组合的部署方式&#xff0c;结合大数据平台、云平台、业务系统、灾备、网络系统及其…

转型AI产品经理(9):“逆反理论”如何应用在Chatbot产品中

心理逆反理论是社会心理学中的一个重要概念&#xff0c;该理论主要探讨了当个体感知到自己的自由被限制或选择受到威胁时&#xff0c;会产生一种想要恢复或维护这些自由的心理倾向&#xff0c;也就是会产生一种逆反心理&#xff0c;试图恢复或重新获得失去的自由。 核心观点 自…

[报错解决]Failed to bind to server socket: amqp://0.0.0.0:5672?maximumConnections

目录 报错信息解决 报错信息 Failed to start Apache ActiveMQ (localhost, ID:rhel-33317-1718469475002-0:1) | org.apache.activemq.broker.BrokerService | main java.io.IOException: Transport Connector could not be registered in JMX: java.io.IOException: Faile…

显示类控件——ProgressBar

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、ProgressBar介绍核心属性代码示例: 设置进度条按时间增长示例: 创建一个蓝色的进度条示例: 反…

LabVIEW程序的常见加密方式

LabVIEW程序的加密对于保护知识产权和敏感数据至关重要。本文将详细介绍LabVIEW程序常用的加密方式&#xff0c;包括VI加密、代码保护、文件加密和通信加密等&#xff0c;帮助开发者选择合适的加密方法来确保程序的安全性和完整性。 LabVIEW程序的常见加密方式 VI加密&#xf…

Javaweb06-Jsp技术

Jsp技术 一.Jsp的运行原理 **概述&#xff1a;**JSP是Java服务器页面&#xff0c;既可以写静态页面代码&#xff0c;也可以写动态页面代码 **特点&#xff1a;**跨平台性&#xff0c;业务代码相分离&#xff0c;组件重用&#xff0c;预编译 运行原理&#xff1a; 客户端发生…

ssldump一键分析网络流量(KALI工具系列二十二)

目录 1、KALI LINUX 简介 2、ssldump工具简介 3、在KALI中使用ssldump 3.1 目标主机IP&#xff08;win&#xff09; 3.2 KALI的IP 4、操作示例 4.1 监听指定网卡 4.2 指定端口 4.3 特定主机 4.4 解码文件 4.5 显示对话摘要 4.6 显示加密数据&#xff08;需要私钥&…

知识普及:什么是边缘计算(Edge Computing)?

边缘计算是一种分布式计算架构&#xff0c;它将数据处理、存储和服务功能移近数据产生的边缘位置&#xff0c;即接近数据源和用户的位置&#xff0c;而不是依赖中心化的数据中心或云计算平台。边缘计算的核心思想是在靠近终端设备的位置进行数据处理&#xff0c;以降低延迟、减…

Python开发者的7个PyCharm必备插件

大家好&#xff0c;本文将推荐使用7个必备的PyCharm IDE设置和插件&#xff0c;希望能帮助了解如何修改和增强IDE体验&#xff0c;使其更适合个人使用&#xff0c;毕竟作为开发者&#xff0c;大部分时间都是在这里工作。 1.String Manipulation 【链接】&#xff1a;https://…

c语言——扫雷游戏(简易版)

目录 前言游戏设计 前言 什么是扫雷游戏&#xff1f; 游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子&#xff0c;同时避免踩雷&#xff0c;踩到一个雷即全盘皆输。 这个游戏对于c语言的初学者来说难度还是挺大的&#xff0c;那我就实现一个初学者也能快速学…

Android Media Framework(六)插件式编程与OMXStore

OpenMAX IL Spec阅读到上一节就结束了&#xff0c;这一节开始正式进入到Framework阅读阶段&#xff0c;我们将了解OpenMAX框架是如何与Android Framework连接的。 1、插件式编程 插件式编程&#xff08;Plugin-based Programming&#xff09;是一种软件开发模式&#xff0c;它…

JavaFX 概述

要从 JavaFX 中充分受益&#xff0c;了解 JavaFX 的设计方式以及对 JavaFX 包含的功能有一个很好的概述是很有用的。本文的目的是为您提供 JavaFX 概述。本文将首先介绍一般的 JavaFX 设计&#xff0c;然后介绍 JavaFX 中的各种特性。 如果您熟悉 Flash/Flex&#xff0c;您会发…

【后端】websocket学习笔记

文章目录 1. 消息推送常见方式1.1 轮询 VS 长轮询1.2 SSE&#xff08;server-sent event)服务器发送事件 2. websocket介绍2.1 介绍2.2 原理2.3 websoket API2.3.1 客户端【浏览器】API2.3.2 服务端API 3. 代码实现3.1 流程分析3.2 pom依赖3.3 配置类3.4 消息格式3.5 消息类 参…

【Css】纯css展开、收起超出的文本

效果 展开 收起 未超出 码 -webkit-line-clamp: 3; 设置限制行数 <div class"wrap"> <inputtype"checkbox"id"exp-txt"><div class"text"><labelfor"exp-txt"class"btn"></label&g…

纷享销客常见问题FAQ

运维和安全职责边界 应用专属是部署在客户私有云或者客户公有云租户的IT环境中的&#xff0c;由纷享销客与客户共同维护系统的稳定性。一般来说客户主要负责维护IT基础环境和账号权限的管理而纷享销客则负责在客户环境中进行应用系统的部署、优化和日常运维工作。在安全方面&am…

OrangePi AIpro 机器人仿真与人工智能应用测评

系列文章目录 前言 本篇文章分为2个部分&#xff0c;第一部分主要搭建了机器人的仿真环境&#xff08;ROS2 MuJoCo等&#xff09;&#xff0c;运行了机械臂及移动机器人相关示例程序&#xff1b;第二部分运行了OrangePi AIpro系统自带的示例程序及昇腾社区官方的示例程序&#…