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

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

目录

一、基本概念

二、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("测试前准备前置操作")
    yield
    print("测试完毕释放资源操作")

def test_example_usage():
    # 测试函数在执行时,无需传入always_used_fixture对应的fixture也会被调用,
    pass


@pytest.fixture(autouse=False)
def always_used_fixture():
    print("测试前准备前置操作")
    yield
    print("测试完毕释放资源操作")

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.param
    return value

def 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 conn
    close_db_conn(conn)


@pytest.fixture
def initialized_table(database_connection):
    create_table(database_connection)
    populate_table(database_connection)
    yield
    truncate_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.py 。pytest会自动发现并加载所有有效的 conftest.py 文件根据其位置确定其作用域,并在相应范围内应用其中定义的fixture和配置。

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

五、什么情况下使用fixture?

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

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

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

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

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

相关推荐
FL16238631292 分钟前
python版本的Selenium的下载及chrome环境搭建和简单使用
chrome·python·selenium
巫师不要去魔法部乱说5 分钟前
PyCharm专项训练5 最短路径算法
python·算法·pycharm
Chloe.Zz12 分钟前
Python基础知识回顾
python
骑个小蜗牛16 分钟前
Python 标准库:random——随机数
python
Trouvaille ~26 分钟前
【机器学习】从流动到恒常,无穷中归一:积分的数学诗意
人工智能·python·机器学习·ai·数据分析·matplotlib·微积分
是十一月末42 分钟前
Opencv实现图像的腐蚀、膨胀及开、闭运算
人工智能·python·opencv·计算机视觉
云空1 小时前
《探索PyTorch计算机视觉:原理、应用与实践》
人工智能·pytorch·python·深度学习·计算机视觉
dowhileprogramming1 小时前
Python 中的迭代器
linux·数据库·python
0zxm2 小时前
08 Django - Django媒体文件&静态文件&文件上传
数据库·后端·python·django·sqlite
灰太狼不爱写代码4 小时前
CUDA11.4版本的Pytorch下载
人工智能·pytorch·笔记·python·学习