Pytest精通指南(07)跨模块共享fixture(conftest.py)

46 篇文章 1 订阅
28 篇文章 1 订阅


请添加图片描述

conftest.py 简介

conftest.py 文件在 pytest 测试框架中是一个特殊的文件,用于存放 fixture 定义、插件注册以及测试配置等。

pytest 发现一个目录中包含 conftest.py 文件时,它会自动加载该文件,并应用其中的配置和 fixture。

这使得 conftest.py 文件成为了一个中心化的地方,用于管理和配置测试相关的各种设置。

conftest.py 用途和含义

Fixture 定义

  • conftest.py 文件主要用于定义fixture
  • Fixture 是 pytest 中用于设置和清理测试环境的特殊函数,它们可以在多个测试函数和类之间共享,并且可以跨文件使用。
  • 通过在 conftest.py 文件中定义fixture,可以确保这些fixture在整个测试会话中都可以被访问。

插件注册

  • conftest.py 还可以用于注册自定义的 pytest 插件。
  • 插件可以用于扩展 pytest 的功能,比如添加新的命令行选项、修改测试报告的格式等。

测试配置

  • conftest.py 文件可以包含测试配置相关的代码,比如设置测试数据的路径、配置日志等。

钩子函数(Hook Functions)

  • conftest.py 允许你定义 pytest 的钩子函数,这些函数会在测试的不同阶段被调用,比如测试开始前、测试结束后等。
  • 通过定义钩子函数,可以控制测试的执行流程,或者添加自定义的行为。

conftest.py 注意事项

文件命名

  • conftest.py 的名称是固定的,不能更改。
  • pytest 只会加载名为 conftest.py 的文件。

作用域

  • conftest.py 中定义的fixture具有全局作用域,可以在同一目录下的所有测试文件中使用。
  • 如果需要在多个包或目录下共享fixture,可以在每个包的根目录下都放置一个 conftest.py文件,并在其中定义相应的fixture

命名冲突

  • 如果多个 conftest.py 文件定义了同名的fixturepytest 会按照特定的优先级规则来选择使用哪个fixture
  • 通常情况下,离测试文件更近的 conftest.py 文件中的fixture会被优先选择。

导入和依赖

  • conftest.py 文件中定义的fixture和其他函数可以被测试文件直接导入和使用,但是需要注意避免循环依赖的问题。

性能考虑

  • 由于 conftest.py 中的fixture可能会在整个测试会话中被多次调用,因此需要注意 fixture 的性能和效率。
  • 尽量避免在 fixture 中执行耗时的操作,或者考虑使用缓存机制来减少重复的计算。

版本兼容性

  • 不同的 pytest 版本可能会有不同的行为或特性,因此在编写 conftest.py 文件时需要注意与当前使用的 pytest 版本的兼容性。

跨模块共享 Fixture

  • pytest 中,当多个模块或文件需要共享相同的 fixture 时,可以将这些 fixture 定义在 conftest.py 文件中。
  • conftest.py 文件允许跨多个模块和文件共享 fixture,这样可以避免在每个测试模块中重复定义相同的 fixture
  • conftest.py 文件可以位于项目的根目录,也可以位于子目录中,只要 pytest 能够发现它。
  • pytest 运行测试时,它会递归地搜索当前目录及其子目录中的 conftest.py 文件,并加载它们。

conftest.py 文件中定义跨模块的 fixture步骤如下:

  1. 在项目的根目录或适当的子目录中创建 conftest.py 文件。
  2. conftest.py 文件中定义 fixture
  3. 在其他测试模块中,通过直接引用或使用 @pytest.mark.usefixtures 装饰器来使用这个 fixture

局部共享

conftest.py文件创建在需要共享的子目录中

conftest.py文件代码
import pytest


@pytest.fixture(scope="session")
def shared_data():
    # 假设这是一些需要跨模块共享的数据
    data = {
        "key1": "value1",
        "key2": "value2"
    }
    yield data
    # 这里可以执行一些清理工作
    # ...

test_case_01.py文件代码
def test_function1(shared_data):
    # 在这里可以使用 shared_data fixture
    assert "value1" == shared_data["key1"]
test_case_02.py文件代码
def test_function2(shared_data):
    # 在这里也可以使用 shared_data fixture
    assert "value2" == shared_data["key2"]
执行效果

请添加图片描述

全局共享

conftest.py文件创建在项目的根目录中

根目录中的conftest.py文件代码
import pytest


@pytest.fixture(scope="session")
def global_session_data():
    """全局共享的 session 级别 fixture"""
    print("\n前置:给测试函数设置一个session")
    data = {"session": "10086"}
    yield data
    print("\n后置:清理环境、删除session")
    # 清理代码可以在这里添加

# 其他的全局 fixture 可以继续添加

子目录中的conftest.py文件代码
import pytest


@pytest.fixture(scope="session")
def shared_data():
    # 假设这是一些需要跨模块共享的数据
    data = {
        "key1": "value1",
        "key2": "value2"
    }
    yield data
    # 这里可以执行一些清理工作
    # ...

test_case_01.py文件代码
def test_function1(shared_data, global_session_data):
    # 在这里可以使用 shared_data fixture
    assert "value1" == shared_data["key1"]
    assert "10086" == global_session_data["session"]
test_case_02.py文件代码
def test_function2(shared_data, global_session_data):
    # 在这里也可以使用 shared_data fixture
    assert "value2" == shared_data["key2"]
    assert "10086" == global_session_data["session"]
执行效果

请添加图片描述

全局和局部中存在同名fixture

在根目录中的conftest.py文件中添加

@pytest.fixture(scope="session")
def shared_data():
    # 假设这是一些需要跨模块共享的数据
    data = {
        "key1": "value1",
        "key2": "value2"
    }
    print("子目录中的fixture被调用")
    yield data
    # 这里可以执行一些清理工作
    # ...

执行效果(查找fixture的顺序为就近原则)

请添加图片描述

指定引用全局fixture

首先,应该避免同名fixture,因为当定义多个同名fixtrue会显得混乱和难以维护;

其次,我们可以通过@pytest.mark.usefixture(NAME)来指定当前测试函数需要引用的fixture

前提,这个被引用的fixtureuseauto参数不为True,因为如果为True,对于能看到该夹具的所有测试,夹具将自动使用。

  • 27
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

需要休息的KK.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值