pytest使用fixtures作为参数化中的参数

elv*_*les 21 python pytest

我想使用fixtures作为pytest.mark.parametrize的参数或具有相同结果的东西.

例如:

import pytest
import my_package

@pytest.fixture
def dir1_fixture():
    return '/dir1'

@pytest.fixture
def dir2_fixture():
    return '/dir2'

@pytest.parametrize('dirname, expected', [(dir1_fixture, 'expected1'), (dir2_fixture, 'expected2')]
def test_directory_command(dirname, expected):
    result = my_package.directory_command(dirname)
    assert result == expected
Run Code Online (Sandbox Code Playgroud)

夹具参数的问题在于夹具的每个参数都会在每次使用时运行,但我不希望这样.我希望能够根据测试选择使用哪种灯具.

Wil*_*ill 10

如果您使用pytest 3.0或更高版本,我认为您应该能够通过编写以下行的方式来解决此特定情况:

@pytest.fixture(params=['dir1_fixture', 'dir2_fixture'])
def dirname(request):
    return request.getfixturevalue(request.param)
Run Code Online (Sandbox Code Playgroud)

文档:http: //doc.pytest.org/en/latest/builtin.html#_pytest.fixtures.FixtureRequest.getfixturevalue

但是,如果您尝试动态加载的夹具已参数化,则无法使用此方法.

或者,您可以使用pytest_generate_tests钩子找出问题.不过,我无法让自己去研究那么多.

  • 我不太确定我是否按照您的要求进行操作。然而,如果您希望在测试用例中执行某种逻辑来确定您需要的设置,您可以通过 request.getfixturevalue() 从那里自由地动态加载夹具。 (2认同)

GGG*_*ser 9

Will 在正确的路径上,您应该使用它request.getfixturevalue来检索夹具。

但是你可以在测试中做对,这更简单。

@pytest.mark.parametrize('dirname, expected', [
    ('dir1_fixture', 'expected1'),
    ('dir2_fixture', 'expected2')])
def test_directory_command(dirname, expected, request):
    result = my_package.directory_command(request.getfixturevalue(dirname))
    assert result == expected
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用lazy-fixture插件:

@pytest.mark.parametrize('dirname, expected', [
    (pytest.lazy_fixture('dir1_fixture'), 'expected1'),
    (pytest.lazy_fixture('dir2_fixture'), 'expected2')])
def test_directory_command(dirname, expected):
    result = my_package.directory_command(dirname)
    assert result == expected
Run Code Online (Sandbox Code Playgroud)

  • 这里是新的 pytester——有两点对我来说不是很明显:(1) `request` 是 `pytest` 的内置固定装置,(2) 应传递 `@pytest.mark.parameterize` 中的固定装置名称作为字符串。将指针作为测试参数传递给函数将引发异常,例如“未找到fixture '<my_fixture at {hex id}>'” (29认同)
  • 第一个对我不起作用,第二个对我有用。 (2认同)

elv*_*les 5

就目前而言,我唯一的解决方案是创建一个返回固定字典的固定装置。

import pytest
import my_package

@pytest.fixture
def dir1_fixture():
    return '/dir1'

@pytest.fixture
def dir2_fixture():
    return '/dir2'

@pytest.fixture
def dir_fixtures(
    dir1_fixture,
    dir2_fixture
    ):
    return {
        'dir1_fixture': dir1_fixture,
        'dir2_fixture': dir2_fixture
    }

@pytest.mark.parametrize('fixture_name, expected', [('dir1_fixture', 'expected1'), ('dir2_fixture', 'expected2')]
def test_directory_command(dir_fixtures, fixture_name, expected):
    dirname = dir_fixtures[fixture_name]
    result = my_package.directory_command(dirname)
    assert result == expected
Run Code Online (Sandbox Code Playgroud)

这不是最好的,因为它没有使用pytest内置的解决方案,但是对我有用。


Rob*_*sak 5

pytest目前不支持此功能。但是有一个开放功能请求:https : //github.com/pytest-dev/pytest/issues/349

  • 创建于2013年。看起来对添加此功能没有太大兴趣。 (2认同)