Python的pytest框架(3)--fixtrue固件

devtools/2024/10/11 9:22:37/

fixture是pytest的一项核心特性,它提供了一种组织和管理测试依赖项(如初始化环境、创建资源、清理操作等)的有效机制。下面将对fixture进行深入讲解,包括其基本概念、作用、使用方式、特性以及高级应用:

目录

一、基本概念

二、fixture的定义与使用

三、fixture特性

fixture 生命周期

fixture参数:

scope(作用域)

autouse(是否自动执行)

params(参数化)

ids(参数别名)

name(固件别名)

fixture依赖:

四、conftest.py--集中管理fixture固件

创建conftest.py文件

使用conftest.py中的内容

五、什么情况下使用fixture?


一、基本概念

fixture 是指在执行特定测试之前设置特定环境或状态,以及在测试完成后清理或还原这些状态的一种机制。它可以用来准备任何测试所需的共享资源,如数据库连接、临时文件、网络服务、模拟数据等。fixture的核心价值在于:

  1. 标准化测试环境:确保每次运行测试时,都基于一致的初始条件,提高测试的可重复性和可靠性。
  2. 资源管理:自动处理资源的创建、使用和销毁,避免测试间资源泄漏或污染。
  3. 代码复用:通过模块化的设计,让多个测试能够共享相同的fixture,减少冗余代码。

二、fixture的定义与使用

fixture在pytest中通过装饰器 @pytest.fixture 标记。一个基本的fixture定义如下:

python">import pytest@pytest.fixture
def example_fixture():# 准备阶段:执行创建或初始化资源的逻辑resource = create_some_resource()yield resource  # 这里yield语句使得测试函数可以在运行时访问到fixture返回的对象# 清理阶段:在测试结束后执行清理逻辑cleanup_resource(resource)

要使用fixture,只需将其作为参数传递给测试函数:

python">def test_example_usage(example_fixture):# 测试函数在执行时,example_fixture对应的fixture会先被调用,# 然后将返回值传递给测试函数作为参数assert do_something_with(example_fixture) == expected_result

三、fixture特性

fixture 生命周期

fixture 的生命周期主要包括三个阶段:

setup: 当测试函数需要某个 fixture 时,pytest 会先调用对应的 fixture 函数。fixture 函数负责初始化所需资源、创建数据或设置特定环境状态。如果 fixture 依赖其他 fixture,那么这些依赖的 fixture 会按照依赖顺序先被 setup。

use: fixture 函数通过 yield 语句返回的值或对象,会在测试函数执行期间作为参数传入并使用。测试函数可以自由操作这些资源,执行测试逻辑。

teardown: 测试函数执行完毕后,pytest 会继续执行 yield 语句之后的清理代码,这里负责释放资源、删除临时文件、关闭数据库连接、恢复环境状态等操作,确保测试的副作用得到清除。

fixture参数:

@pytest.fixture(scope="作用域",autouse="是否自动执行",params="参数化",ids="参数别

名",name="固件别名")

我们分开来讲述这些参数的具体作用

scope(作用域)

控制fixture的作用域,可选值包括 "function"(默认为function)、"class"、"module"、"package" 或 "session"。作用域决定了fixture的生命周期和复用范围:

function: 每当有测试函数请求此fixture时,pytest会为其创建一个新的fixture实例。这意味着每个测试函数都会得到一个独立的fixture副本。

class: 在类中首个依赖此fixture的测试函数执行前,pytest会创建一个fixture实例。该实例会被类中所有依赖此fixture的测试函数共享。
module: 在模块中首个依赖此fixture的测试函数执行前,pytest会创建一个fixture实例。该实例会被模块内所有依赖此fixture的测试函数共享。
package: 在包中首个依赖此fixture的测试函数执行前,pytest会创建一个fixture实例。该实例会被包内所有依赖此fixture的测试函数共享。
session: 在测试会话开始时,pytest会创建一个fixture实例。该实例会被会话中所有依赖此fixture的测试函数共享。

python">@pytest.fixture(scope="module")
def module_level_fixture():...#scope='module' 只创建一次,会作用到整个模块

autouse(是否自动执行)

如果设为 True,则无需显式在测试函数签名中指定该fixture,它会自动应用于所有匹配其作用域的测试,默认为False。

python">@pytest.fixture(autouse=True)
def always_used_fixture():print("测试前准备前置操作")yieldprint("测试完毕释放资源操作")def test_example_usage():# 测试函数在执行时,无需传入always_used_fixture对应的fixture也会被调用,pass@pytest.fixture(autouse=False)
def always_used_fixture():print("测试前准备前置操作")yieldprint("测试完毕释放资源操作")def test_example_usage(always_used_fixture):# 测试函数在执行时,需传入always_used_fixture对应的fixture才被调用,pass

params(参数化)

pytest 支持对 fixture 进行参数化,这意味着一个 fixture 可以根据不同的输入参数产生多种不同的预备状态。参数化 fixture 可以极大地提高测试的覆盖范围和灵活性。要实现参数化 fixture,可以使用 pytest.mark.parametrize 装饰器同时装饰 fixture 函数和依赖它的测试函数,或者直接在 fixture 函数上使用 params 关键字参数。以下是一个参数化 fixture 的示例:

python">import pytest@pytest.fixture(params=[1, 2, 3])
def input_fixture(request):value = request.paramreturn valuedef test_multiply_by_two(input_fixture):assert input_fixture * 2 == input_fixture + input_fixture

在这个例子中,input_fixture是一个参数化的fixture,其params关键字参数设置为列表[1, 2, 3]。这意味着每次test_multiply_by_two函数运行时,input_fixture将会接收到列表中的一个不同值。因此,test_multiply_by_two函数会被执行三次,分别使用参数值1, 2 和 3。

ids(参数别名)

为参数化fixture的每个实例提供易于识别的标识,便于在测试报告中区分。

python">@pytest.fixture(params=[1, 2, 3], ids=["one", "two", "three"])
def named_parametrized_fixture(request):value = request.param...

name(固件别名)

自定义fixture的名称,仅在需要覆盖默认生成的fixture名称时使用。

python">@pytest.fixture(name="custom_name")
def my_fixture():...

fixture依赖:

fixture之间可以相互依赖。一个fixture在其定义中可以通过接受其他fixture作为参数来声明依赖关系。当依赖的fixture被请求时,pytest会确保先执行依赖fixture的setup部分,再执行当前fixture,最后在测试结束时按照相反顺序执行清理操作。

python">@pytest.fixture
def database_connection():conn = establish_db_conn()yield connclose_db_conn(conn)@pytest.fixture
def initialized_table(database_connection):create_table(database_connection)populate_table(database_connection)yieldtruncate_table(database_connection)def test_query(initialized_table):rows = execute_query(initialized_table)assert len(rows) > 0

在这里,initialized_table fixture依赖于database_connection fixture。当test_query函数请求initialized_table时,pytest会确保先执行database_connection的setup部分(建立数据库连接),然后执行initialized_table的setup(创建表并填充数据)。测试结束后,先清理initialized_table(清空表),再清理database_connection(关闭连接)。

四、conftest.py--集中管理fixture固件

conftest.py 是 pytest 测试框架中一个特殊且非常重要的文件,主要用于存放与测试相关的配置、全局设置以及可复用的fixture(固件)

创建conftest.py文件

在需要使用fixture或进行特定配置的目录下创建名为 conftest.py 的文件。可以创建在项目根目录下(影响整个项目),也可以创建在特定的测试子目录下(仅影响该目录及其子目录)

在conftest.py文件中可以定义fixture固件,也可以通过 pytest.mark 装饰器为所有测试添加标记(markers)

使用conftest.py中的内容

无需在测试代码中显式导入或引用 conftest.pypytest自动发现并加载所有有效的 conftest.py 文件根据其位置确定其作用域,并在相应范围内应用其中定义的fixture和配置。

总结而言,conftest.py 文件是pytest框架中用于集中管理测试配置、定义可复用fixture以及定制测试执行流程的关键组件。通过在适当位置创建 conftest.py 并编写相应的代码,可以极大地提升测试代码的组织性、可维护性和执行效率。

五、什么情况下使用fixture?

需要共享资源或数据:当你有一组测试都需要访问同一个数据库、文件、网络连接或其他资源时,用fixture来统一管理和初始化这些资源,确保每个测试获得的是正确且独立的状态。

需要复杂的环境设置:如果你的测试需要复杂的环境配置,如启动服务、设置系统权限、模拟外部接口响应等,使用fixture来封装这些复杂的设置和清理逻辑,使测试代码聚焦于核心测试行为。

需要重复的初始化或清理:如果有多个测试需要进行相似的初始化(如填充固定测试数据)或清理(如删除临时文件、重置系统状态)操作,使用fixture可以避免在每个测试中重复编写这些代码。

需要参数化测试:当你希望一个测试用例针对不同输入参数运行多次时,可以使用参数化的fixture为测试函数提供一组或多组不同的预备环境或数据,从而增加测试覆盖率。

希望以上内容能帮助大家高效理解pytest框架的fixture固件,让fixture帮助测试变得更高效可靠


http://www.ppmy.cn/devtools/9543.html

相关文章

《中学科技》是什么级别的刊物?如何投稿?

《中学科技》是什么级别的刊物?如何投稿? 《中学科技》创刊于1976年,由上海世纪出版(集团)有限公司主管,上海科技教育出版社有限公司主办的省级学术期刊,《中学科技》以传播科技知识、启迪智慧…

C# 语言类型(二)—预定义类型之字符串及字符类型简述

总目录 C# 语法总目录 参考链接: C#语法系列:C# 语言类型(一)—预定义类型值之数值类型 C#语法系列:C# 语言类型(二)—预定义类型之字符串及字符类型简述 C#语法系列:C# 语言类型(三)—数组/枚举类型/结构体 C#语法系列:C# 语言类型(四)—传递参数及其修饰符 C#语法…

【Vue3源码学习】— CH3.2 VNode解析(下)

VNode解析—下 4. normalizeChildren4.1 源码解析4.2 位运算符 |= 的应用4.2.1 按位或(|)4.2.2 赋值4.2.3 使用场景4.2.4 源码中`vnode.patchFlag |= PatchFlags.DYNAMIC_SLOTS`说明4.3 `;(children as RawSlots)._ = SlotFlags.STABLE` 说明5. Vue 应用的实例化和挂载流程5.…

mysql面试题四(事务)

目录 1.什么是数据库的事务 1. 原子性(Atomicity) 2. 一致性(Consistency) 3. 隔离性(Isolation) 4. 持久性(Durability) 2.事务的并发问题 1. 脏读(Dirty Read&am…

天星金融细说社保 筑牢民生保障防线

随着经济的蓬勃发展与社会的不断进步,社保制度作为保障人民群众切身利益的重要机制,其重要性日益凸显。近年来,社保体系的不断完善与更新,使得群众对社保的参与意识逐渐增强。然而,却有人利用群众的需求,以…

49.基于SpringBoot + Vue实现的前后端分离-爱心公益网站系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统,采用SpringBoot Vue框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得基于SpringBoot Vue技术的爱心公益网站系统设计与实现管理工作…

HarmonyOS开发实例:【图片编辑应用】

介绍 本篇Codelab通过动态设置元素样式的方式,实现几种常见的图片操作,包括裁剪、旋转、缩放和镜像。效果如图所示: 相关概念 [image组件]:图片组件,用来渲染展示图片。[div组件]:基础容器组件&#xff0…

java高校办公室行政事务管理系统设计与实现(springboot+mysql源码+文档)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的闲一品交易平台。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: 基于mvc的高校办公室行政…