0

我想要实现的基本上是这个,但是有一个类范围的参数化夹具。

问题是,如果我generate_fixture and inject_fixture从帮助文件中导入方法 (),则注入夹具代码似乎被调用得太晚了。这是一个完整的工作代码示例:

# all of the code in one file
import pytest
import pytest_check as check

def generate_fixture(params):
    @pytest.fixture(scope='class', params=params)
    def my_fixture(request, session):
        request.cls.param = request.param
        print(params)

    return my_fixture

def inject_fixture(name, someparam):
    globals()[name] = generate_fixture(someparam)

inject_fixture('myFixture', 'cheese')

@pytest.mark.usefixtures('myFixture')
class TestParkingInRadius:

    def test_custom_fixture(self):
        check.equal(True, self.param, 'Sandwhich')

如果我将生成和注入助手移动到他们自己的文件中(根本不更改它们),我会得到一个未找到固定装置的错误,即如果测试文件看起来像这样:

import pytest
import pytest_check as check

from .helpers import inject_fixture

inject_fixture('myFixture', 'cheese')

@pytest.mark.usefixtures('myFixture')
class TestParkingInRadius:

    def test_custom_fixture(self):
        check.equal(True, self.param, 'Sandwhich')

我在设置时遇到错误:E fixture 'myFixture' not found后跟可用夹具列表(不包括注入的夹具)。

有人可以帮助解释为什么会这样吗?必须在每个测试文件中定义这些函数有点违背了这样做的全部意义(保持干燥)。

4

1 回答 1

2

我解决了这个问题。

将注入夹具方法放在不同的文件中会更改该方法的全局范围。它在同一个文件中工作的原因是调用者和注入夹具方法共享相同的全局范围。

使用本机检查包并获取调用者的范围解决了这个问题,这里有完整的样板工作代码,包括通过内置request夹具进行的类自省:

import inspect
import pytest

def generate_fixture(scope, params):
    @pytest.fixture(scope=scope, params=params)
    def my_fixture(request):
        request.cls.param = request.param
        print(request.param)

    return my_fixture

def inject_fixture(name, scope, params):
    """Dynamically inject a fixture at runtime"""
    # we need the caller's global scope for this hack to work hence the use of the inspect module
    caller_globals = inspect.stack()[1][0].f_globals
    # for an explanation of this trick and why it works go here: https://github.com/pytest-dev/pytest/issues/2424
    caller_globals[name] = generate_fixture(params)
于 2022-02-14T02:46:45.627 回答