以编程方式在 pytest 插件中注册夹具

Programmatically register a fixture in a pytest plugin

我正在寻找一种方法 运行 来自 Python 的一些 pytest 单元测试并动态注册一个 pytest fixture。如 Pytest 文档中所述,当 运行ning 以编程方式进行测试时 their behaviour can be altered with a custom plugin。我有以下设置

validation.py(包含 运行 的测试)

def test_valid(new_fixture):
    assert new_fixture > 0

启动时,

import pytest

new_fixture_value = 36

class FixtureRegPlugin(object):
    def pytest_sessionstart(self):
        print('Test session start')

        @pytest.fixture
        def new_fixture():
            return new_fixture_value

pytest.main(['-sv', './validation.py'], plugins=[FixtureRegPlugin()])

这里我们 运行 使用自定义插件在 validation.py 中进行测试,该插件为 pytest_sessionstart 注册了一个挂钩。此挂钩在测试会话开始时执行,我可以按预期看到打印输出。但是,new_fixture 未注册,因此测试失败并出现 "fixture not found" 错误。

目标是在 运行 时间修改夹具的结果,因此我不能只将其定义放在 validation.py.

您有什么理由不想在 conftest.py 文件中使用 @pytest.fixture(scope='session') 而不是编写自己的插件吗?这能否实现您正在寻找的在运行时更改夹具的功能?

无论如何,如果您更改缩进并将 self 添加到 new_fixture 的参数中,它应该可以工作。

        @pytest.fixture
        def new_fixture():
            return new_fixture_value

    @pytest.fixture(scope='session')
    def new_fixture(self):
        return new_fixture_value

您可以在命令行上使用 --setup-show 查看设置和拆卸。

script.py”的内容:

import pytest


class FixtureRegPlugin(object):

    @pytest.fixture(scope='session')
    def session_fixture(self):
        pass

    @pytest.fixture(scope='module')
    def module_fixture(self):
        pass

    @pytest.fixture(scope='function')
    def function_fixture(self):
        pass


pytest.main(['--setup-show', './validation.py'], plugins=[FixtureRegPlugin()])

validation.py 的内容:

def test_A(session_fixture, module_fixture, function_fixture):
    pass

def test_B(session_fixture, module_fixture, function_fixture):
    pass

运行 python script.py:

Test session start
=================================== test session starts
platform linux -- Python 3.6.2, pytest-3.2.2, py-1.4.34, pluggy-0.4.0
rootdir: /home/Whosebug, inifile:
collected 2 items                                                                                                                                                                                     

validation.py 
SETUP    S session_fixture
  SETUP    M module_fixture
      SETUP    F function_fixture
        validation.py::test_A (fixtures used: function_fixture, module_fixture, session_fixture).
      TEARDOWN F function_fixture
      SETUP    F function_fixture
        validation.py::test_B (fixtures used: function_fixture, module_fixture, session_fixture).
      TEARDOWN F function_fixture
  TEARDOWN M module_fixture
TEARDOWN S session_fixture

=================================== 2 passed in 0.00 seconds