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


    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定义如下:

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

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

    1. def test_example_usage(example_fixture):
    2. # 测试函数在执行时,example_fixture对应的fixture会先被调用,
    3. # 然后将返回值传递给测试函数作为参数
    4. 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的测试函数共享。

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

    autouse(是否自动执行)

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

    1. @pytest.fixture(autouse=True)
    2. def always_used_fixture():
    3. print("测试前准备前置操作")
    4. yield
    5. print("测试完毕释放资源操作")
    6. def test_example_usage():
    7. # 测试函数在执行时,无需传入always_used_fixture对应的fixture也会被调用,
    8. pass
    9. @pytest.fixture(autouse=False)
    10. def always_used_fixture():
    11. print("测试前准备前置操作")
    12. yield
    13. print("测试完毕释放资源操作")
    14. def test_example_usage(always_used_fixture):
    15. # 测试函数在执行时,需传入always_used_fixture对应的fixture才被调用,
    16. pass

    params(参数化)

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

    1. import pytest
    2. @pytest.fixture(params=[1, 2, 3])
    3. def input_fixture(request):
    4. value = request.param
    5. return value
    6. def test_multiply_by_two(input_fixture):
    7. 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的每个实例提供易于识别的标识,便于在测试报告中区分。

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

    name(固件别名)

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

    1. @pytest.fixture(name="custom_name")
    2. def my_fixture():
    3. ...

    fixture依赖:

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

    1. @pytest.fixture
    2. def database_connection():
    3. conn = establish_db_conn()
    4. yield conn
    5. close_db_conn(conn)
    6. @pytest.fixture
    7. def initialized_table(database_connection):
    8. create_table(database_connection)
    9. populate_table(database_connection)
    10. yield
    11. truncate_table(database_connection)
    12. def test_query(initialized_table):
    13. rows = execute_query(initialized_table)
    14. 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帮助测试变得更高效可靠

  • 相关阅读:
    社区分享|中南民族大学基于JumpServer构建规范、便利的运维安全体系
    面具安装LSP模块时提示 Unzip error错误的解决办法
    [pytorch] 2D + 3D EfficientNet代码 实现,改写
    centos查询服务器硬件信息
    etcd安装
    python程序打包(Mac/Window)
    PlatformIO+ESP32+Vscode+DS18B20温度传感器(一直输出-127)
    在线Web页面测试工具-WebPageTest
    Spire.Office for Java 8.9.7 Crack
    网络服务器和客户端的编写
  • 原文地址:https://blog.csdn.net/qq_52758588/article/details/137921371