💻 Pytest Fixture 🌀

基于 Pytest 8.3.4版本

什么是fixture

fixture是pytest用于将测试前后进行预备、清理工作的代码分离出核心测试逻辑的一种机制。
类似于unittest中的setUp和tearDown。

使用fixture的好处:

  • 代码重用
    将常用的 setup 和 teardown 逻辑封装在 fixture 中,避免在每个测试用例中重复编写相同的代码。
  • 测试隔离
    每个测试用例都可以请求独立的 fixture 实例,确保测试之间的相互独立性,避免状态污染。
  • 管理复杂依赖
    fixture 可以用于创建和管理测试所需的各种依赖,例如数据库连接、模拟对象、配置文件等。
  • 提高可读性和可维护性
    将 setup 和 teardown 逻辑与测试用例代码分离,使测试代码更加清晰易懂,也更容易维护。
  • 灵活的作用域
    fixture 可以定义不同的作用域(例如函数级别、类级别、模块级别、会话级别),以满足不同的需求。

如何定义fixture

fixture 的定义通常在 conftest.py 文件中,也可以在测试文件中定义。

①conftest.py

注意:虽然conftest.py是python模块,但它不能被测试文件导入,即import conftest是不允许的。

在 conftest.py 文件中定义 fixture 时,可以使用 pytest_fixture_setuppytest_fixture_teardown 钩子函数来设置和清理 fixture。

import pytest

@pytest.fixture(scope="function")
def my_fixture():
    print("Setting up my_fixture")
    yield
    print("Tearing down my_fixture")

使用:

def test_my_fixture(my_fixture):
    print("Running test with my_fixture")

②测试文件

在测试文件中定义 fixture 时,可以使用 pytest.fixture 装饰器来定义 fixture。

import pytest

@pytest.fixture(scope="function")
def my_fixture():
    print("Setting up my_fixture")
    yield
    print("Tearing down my_fixture")

使用:

def test_my_fixture(my_fixture):
    print("Running test with my_fixture")

fixture作用域Scope

5种作用域:

  • function:函数级别(默认)
    每个测试函数都会创建一个新的 fixture 实例
  • class:类级别
    每个测试类都会创建一个新的 fixture 实例
  • module:模块级别
    每个测试模块都会创建一个新的 fixture 实例
  • session:会话级别
    每个测试会话都会创建一个新的 fixture 实例
  • package:包级别
    每个测试包都会创建一个新的 fixture 实例

可以在@pytest.fixture装饰器中指定scope参数来设置fixture的作用域。

import pytest

@pytest.fixture(scope="module")
def shared_resource():
    """模块级别的共享资源"""
    resource = ... # 创建共享资源的代码
    yield resource
    # 清理共享资源的代码

fixture的返回值

fixture可以返回任何值,包括复杂对象、数据库连接、模拟对象等。
fixture的返回值可以作为测试函数的参数传递给测试函数。
fixture的返回值也可以在测试函数中使用。

import pytest

@pytest.fixture
def my_fixture():
    return "Hello, World!"

内置fixture

fixture源码实现