news 2026/2/18 17:05:36

pytest 的 request fixture:实现个性化测试需求

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
pytest 的 request fixture:实现个性化测试需求

在之前深入理解pytest-repeat插件的工作原理一文中,我们看到pytest_repeat源码中有这样一段

  1. @pytest.fixture

  2. def __pytest_repeat_step_number(request):

  3. marker = request.node.get_closest_marker("repeat")

  4. count = marker and marker.args[0] or request.config.option.count

  5. ......

看到参数为request,我们知道fixture装饰的函数入参,只能是其他fixture,所以这里request一定也是fixture。那它到底怎么用呢?这篇文章将详细介绍,并通过实战项目加深理解。

request fixture

The request fixture is a special fixture providing information of the requesting test function.这是pytest官方文档的介绍,意思就是请求fixture是一个特殊的fixture,提供请求测试函数的信息。

源码直达,感兴趣的朋友可以查看源码FixtureRequest

文档直达

request.node

当前测试用例的节点对象,表示当前执行的测试用例。可以使用该对象获取测试用例的名称、文件路径、测试类等信息。

  1. import pytest

  2. @pytest.fixture

  3. def my_fixture(request):

  4. node = request.node

  5. print(f"Current test case: {node.name}")

  6. print(f"Test file path: {node.fspath}")

  7. print(f"Test class: {node.getparent}")

  8. def test_demo(my_fixture):

  9. pass

输出结果为:

  1. Current test case: test_demo

  2. Test file path: /Users/pxl/test_dir/test_demo.py

  3. Test class: <bound method Node.getparent of <Function test_demo>>

fixture 使用了request参数,并通过request.node获取了当前测试用例的相关信息。具体来说,我们打印了当前测试用例的名称、文件路径和测试类名称。

request.config

前运行的配置对象,表示当前 Pytest 的配置信息。可以使用该对象获取命令行参数、配置文件设置等信息。

pytest.ini

  1. [pytest]

  2. markers =

  3. p0: 冒烟

  4. p1: 功能

  1. @pytest.fixture

  2. def my_fixture(request):

  3. config = request.config

  4. print(f"Command line arguments: {config.option}")

  5. print(f"INI file options: {config.getini('markers')}")

该 fixture 使用了request参数,并通过request.config获取了当前 Pytest 的配置信息。具体来说,我们打印了命令行参数和配置文件中的一个选项。

request.param

当前 fixture 的参数,表示当前 fixture 的实例所需的参数值

  1. @pytest.fixture(params=[1, 2, 3])

  2. def my_fixture(request):

  3. param_value = request.param

  4. print(f"Current parameter value: {param_value}")

  5. return param_value

该 fixture 使用了request参数,并通过request.param获取了当前实例所需的参数值。

request.fixturename

返回当前 fixture 的名称。

  1. @pytest.fixture

  2. def my_fixture(request):

  3. fixture_name = request.fixturename

  4. print(f"Current fixture name: {fixture_name}")

我们使用request.fixturename获取了当前 fixture 的名称,并将其打印出来.

request.fixturenames

返回当前测试函数所使用的所有 fixture 的名称列表

  1. @pytest.fixture

  2. def my_fixture(request):

  3. pass

  4. def test_example(my_fixture, request):

  5. fixture_names = request.fixturenames

  6. print(f"Current fixture name: {fixture_names}")

我们使用request.fixturenames获取了test_example使用的所有 fixture 的名称

request.cls

当前测试类的类对象。

  1. class TestClass:

  2. @pytest.fixture

  3. def my_fixture(self, request):

  4. class_obj = request.cls

  5. print(f"Current class object: {class_obj}")

使用request.cls获取了当前测试类的类对象,并将其打印出来。

request.addfinalizer(finalizer_func)

在 fixture 完成后执行指定的函数。

  1. @pytest.fixture

  2. def my_fixture(request):

  3. def finalizer_func():

  4. print("Finalizer function called")

  5. request.addfinalizer(finalizer_func)

  6. print("Fixture setup")

我们使用request.addfinalizer()方法注册了一个 finalizer 函数finalizer_func。该函数将在 fixture 执行完毕后被调用,并打印一条消息。

request.applymarker(marker)

为当前测试用例或 fixture 应用指定的 marker。

  1. @pytest.fixture

  2. def my_fixture(request):

  3. request.applymarker(pytest.mark.slow)

我们使用request.applymarker()方法为当前 fixture 添加了一个pytest.mark.slow的标记。这个标记可以被 Pytest 识别并用于特定的测试运行策略。

request.config.getoption(name)

获取命令行选项的值。

  1. @pytest.fixture

  2. def my_fixture(request):

  3. my_option = request.config.getoption("--my_option")

  4. print(f"Value of --my_option: {my_option}")

我们使用request.config.getoption()方法获取了命令行选项--my_option的值,并将其打印出来。

request.module

当前测试用例所属的模块对象

  1. def my_fixture(request):

  2. module_obj = request.module

  3. print(f"Current module object: {module_obj}")

我们使用request.module获取了当前测试用例所属的模块对象,并将其打印出来

request.param_index

参数化 fixture 的参数索引

  1. @pytest.fixture(params=[1, 2, 3])

  2. def my_fixture(request):

  3. param_value = request.param

  4. param_index = request.param_index

  5. print(f"Current parameter value: {param_value}")

  6. print(f"Current parameter index: {param_index}")

  7. return param_value

我们对带有参数的my_fixturefixture 进行了参数化。使用request.param_index可以获取当前参数在参数列表中的索引,并将其打印出来。

request.keywords

当前测试用例的关键字集合

  1. @pytest.fixture

  2. def my_fixture(request):

  3. keywords = request.keywords

  4. print(f"Current test keywords: {keywords}")

我们使用request.keywords获取了当前测试用例的关键字集合,并将其打印出来

request.getfixturevalue(fixturename)

获取已注册的 fixture 对象的值

  1. import pytest

  2. @pytest.fixture

  3. def my_fixture():

  4. return "Hello, Fixture!"

  5. def test_example(request):

  6. fixture_value = request.getfixturevalue("my_fixture")

  7. assert fixture_value == "Hello, Fixture!"

实战

到这里request fixture的常用属性和方法应该了解差不多了。更多属性和方法,可以参考官方文档。

接下来我们就利用request属性实现数据库环境的切换。看实现代码

conftest.py

  1. def pytest_addoption(parser):

  2. parser.addoption("--test", action="store_true", help="Run tests in test mode")

  3. @pytest.fixture(scope="session")

  4. def config_parser(request):

  5. class Clazz(object):

  6. config = ConfigParser()

  7. config.read(config_path)

  8. section = 'test' if request.config.getoption("--test") else 'prod'

  9. log.info(f"section: {config.sections()}")

  10. db_host = config.get(section, 'host')

  11. db_port = config.get(section, 'port')

  12. db_username = config.get(section, 'username')

  13. db_password = config.get(section, 'password')

  14. db_database = config.get(section, 'database')

  15. api_url = config.get(section, 'url')

  16. return Clazz

  17. @pytest.fixture(scope="session")

  18. def db_connection(config_parser):

  19. db_conn = MySQLDB(

  20. config_parser.db_host,

  21. int(config_parser.db_port),

  22. config_parser.db_username,

  23. config_parser.db_password,

  24. config_parser.db_database

  25. )

  26. yield db_conn

  27. db_conn.close()

  1. config_parser是一个会话级别的 fixture,它返回一个配置解析器对象。这个配置解析器对象可以读取配置文件,并根据传入的命令行参数--test来确定读取哪个配置文件的特定部分(测试环境或生产环境)。具体流程如下:

    a. 首先,在pytest_addoption函数中,通过调用parser.addoption()方法来添加一个命令行选项--test,它的作用是告诉 pytest 在测试模式下运行。

    b. 在config_parserfixture 中,我们首先创建了一个名为Clazz的类,它包含了从配置文件中读取的各个配置项的值。

    c. 根据传入的--test参数值,决定使用测试环境还是生产环境的配置。如果--test参数被指定,则使用配置文件中的test部分,否则使用prod部分。

    d. 通过config.get()方法获取具体的配置项的值,例如db_hostdb_portdb_username等。

    e. 最后,将Clazz类作为返回值,供其他测试代码使用。

  2. db_connection是一个会话级别的 fixture,它返回一个数据库连接对象。这个对象在测试期间可以被使用,并在测试完成后进行关闭。具体流程如下:

    a. 在db_connectionfixture 中,我们创建了一个MySQLDB对象,将从config_parserfixture 中获取的数据库连接参数传入。

    b. 使用yield语句将数据库连接对象返回给测试代码。yield使得这个 fixture 可以在测试期间提供数据库连接,而在测试完成后继续执行下面的代码。

    c. 在yield之后的代码将在测试完成后执行,这里使用db_conn.close()来关闭数据库连接。

可以看到我们正是使用request.config.getoption这个方法来 获取命令行选项的值。

这段代码展示了如何使用 pytest 的 fixture 来管理测试环境和资源的初始化和清理。通过使用会话级别的 fixture,可以确保在整个测试会话期间只进行一次配置解析和数据库连接操作,避免重复的开销和不必要的操作。

后续

到这里我们有攻克了一个知识点request,不仅介绍了它的基本用法,也介绍了笔者在工作中真实使用场景。多加尝试,才能印象深刻。

感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/17 9:37:45

ResNet18保姆级教程:小白10分钟搞定物体识别,1块钱起

ResNet18保姆级教程&#xff1a;小白10分钟搞定物体识别&#xff0c;1块钱起 引言&#xff1a;文科生也能玩转AI图像识别 作为一个对AI感兴趣的文科生&#xff0c;你是否曾被满屏的Python代码吓退&#xff1f;看到"卷积神经网络"、"特征提取"这些术语就头…

作者头像 李华
网站建设 2026/2/16 17:06:36

基于Qwen2.5-7B的结构化输出实践|附vLLM加速技巧

基于Qwen2.5-7B的结构化输出实践&#xff5c;附vLLM加速技巧 一、引言&#xff1a;为何结构化输出成为大模型落地的关键能力&#xff1f; 随着大语言模型&#xff08;LLM&#xff09;在企业级应用中的深入&#xff0c;非结构化文本生成已无法满足自动化系统集成的需求。无论是…

作者头像 李华
网站建设 2026/2/17 8:10:41

ResNet18物体识别避坑指南:云端GPU开箱即用免配置

ResNet18物体识别避坑指南&#xff1a;云端GPU开箱即用免配置 引言 作为一名刚转行AI的小白&#xff0c;你是否也遇到过这样的困境&#xff1a;跟着网上的ResNet18教程配置环境&#xff0c;折腾了三天却还在和CUDA报错作斗争&#xff1f;明明只是想快速体验物体识别效果&…

作者头像 李华
网站建设 2026/2/15 11:02:37

物体识别API开发:ResNet18云端服务,比自建便宜60%

物体识别API开发&#xff1a;ResNet18云端服务&#xff0c;比自建便宜60% 引言 作为一名全栈工程师&#xff0c;当你接到开发智能相册的私活时&#xff0c;最头疼的莫过于物体识别功能的实现。传统方案要么需要自建GPU服务器&#xff08;成本高、维护难&#xff09;&#xff…

作者头像 李华
网站建设 2026/2/18 7:36:35

从照片到深度图|AI单目深度估计-MiDaS镜像一键部署指南

从照片到深度图&#xff5c;AI单目深度估计-MiDaS镜像一键部署指南 &#x1f310; 技术背景与应用价值 在计算机视觉领域&#xff0c;三维空间感知一直是实现智能交互、增强现实&#xff08;AR&#xff09;、机器人导航和自动驾驶的核心能力。然而&#xff0c;传统深度感知依赖…

作者头像 李华
网站建设 2026/2/17 4:34:10

ResNet18联邦学习初探:云端GPU模拟多节点

ResNet18联邦学习初探&#xff1a;云端GPU模拟多节点 引言&#xff1a;当隐私保护遇上联邦学习 想象一下&#xff0c;医院A想用患者数据训练AI诊断模型&#xff0c;但法律不允许共享原始数据&#xff1b;同时医院B、C也有同样需求。传统集中式训练需要把所有数据上传到中心服…

作者头像 李华