Pytest动态夹具范围-如何设置夹具范围并将其应用于所有测试?

时间:2019-10-29 09:06:27

标签: pytest

我正在尝试使用pytest固定装置动态范围。 文档指出范围将在夹具定义期间确定;这是否意味着一旦在pytest run中动态设置了范围,该范围将适用于所有使用夹具的测试? 在测试运行期间是否有可能影响范围(即使用标记)? 如果没有,如何更改配置(不使用命令行arg)来更改范围?

我试图添加一个标记并将其值用作pytest_generate_tests中的作用域,但是夹具定义在pytest_generate_tests之前运行。

def pytest_generate_tests(metafunc):
    fixture_scope = metafunc.definition.get_closest_marker('scope').args
    if fixture_scope is not None:
        metafunc.config.addinivalue_line('markers', f'scope:{fixture_scope[0]}')


def determine_scope(fixture_name, config):
    scope = [i for i in config.getini('markers') if 'scope' in i][0]
    if scope:
        return scope.split(':')[-1]
    return "function"


@pytest.fixture(scope=determine_scope)
def some_fixture():

1 个答案:

答案 0 :(得分:1)

我建议使用env var作为范围。如果要更改范围,请更改env var。仅当灯具的当前范围结束时,范围更改才会生效。

@pytest.fixture(scope=os.environ.get("fixture_scope","function))
def fixture_name():
    pass

def test_change_fixture():
    os.environ["fixture_scope"] = "class"

我尚未测试此代码。但是我发现使用env var在pytest运行的不同阶段之间传递变量非常有用。您也可以使用动态配置文件或类似的文件。

实现此目标的丑陋方法是拥有4个相同的灯具,并根据需要获取相关的灯具。

def fixture_code():
    pass

@pytest.fixture(scope="module)
def module_fixture():
    fixture_code()

@pytest.fixture(scope="session")
def session_fixture():
    fixture_code()

# similar fixtures for other scopes

@pytest.fixture(scope="session")
def fixture_provider(request, module_fixture, session_fixture, .....):
    if request.param['scope'] == "module":
       return module_fixture
    elif request.param['scope'] == "session":
       return session_fixture
    .
    .
    .

@pytest.mark.parametrize("scope",[os.environ.get("fixture_scope")], indirect=True)
def test_abc(fixture_provider):
   #use fixture provider.

您可以使用代码设置env var以获得相关的灯具。