【问题标题】:Pytest dynamic fixture scope - how to set and will the fixture scope apply to all tests?Pytest 动态夹具范围 - 如何设置夹具范围并将其应用于所有测试?
【发布时间】:2020-02-24 12:04:54
【问题描述】:

我正在尝试使用 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():

【问题讨论】:

  • 也许你应该在你的问题中包含你为什么要这样做,以便有人可以建议一种替代方法。
  • 我想避免重复代码;我有一些代码在某些测试的功能级别和其他测试的模块级别需要。我想为 2 个用例重复使用相同的夹具
  • 只是想:你可以把这段代码放在一个函数foo中重用,然后定义两个fixture:一个具有函数范围,另一个具有模块范围,实际上只是调用这个函数foo和然后根据需要用固定装置装饰测试。
  • 这是我作为解决方法所做的;但是,创建 2 个仅具有不同范围的精确夹具,特别是如果您需要使用多个夹具来创建,这并不是真正可读的。

标签: pytest


【解决方案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 以获取相关夹具。

【讨论】:

  • 这不适用于灯具。我试图在测试之前设置环境变量,但我认为范围仅在测试运行开始时确定一次。
  • 你能提供你用来检查解决方案正确性的代码吗?它可以帮助我想出更好的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-16
  • 2022-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 2018-01-30
相关资源
最近更新 更多