pytest.mark.parametrize 中的可选参数

and*_*Kox 8 python testing pytest

我用 pytest 框架进行了长时间的测试。代码是这样的:

@pytest.fixture(scope='function')
def my_setup():
        execute_setup_actions()

@pytest.mark.parametrize('name, arg1', [
        ('test_1', 1),
        ...
        ('test_100', 100),
])
def test_mine(name, arg1):
         execute_test_case(arg1)
Run Code Online (Sandbox Code Playgroud)

现在,我需要为 @pytest.mark.parametrize 编写的一个新测试中使用的arg2my_setup 固定装置提供一个可选参数。my_setup(arg2=None)当然,我可以为其他 100 个测试放入'name, arg1, arg2'parametrize添加None参数值,但是还有其他方法可以以更漂亮的方式完成这样的事情吗?

谢谢!

小智 0

如果要将参数传递给固定装置,则应使用工厂作为固定装置模式,如文档中所述:

@pytest.fixture(scope='function')
def my_setup():
    def _my_setup(arg2=None)
        execute_setup_actions(arg2)

    return _my_setup
Run Code Online (Sandbox Code Playgroud)

然后,在你的测试中:

@pytest.mark.parametrize('name, arg1', [
        ('test_1', 1),
        ...
        ('test_100', 100),
])
def test_mine(name, arg1, my_setup):
    my_setup(arg2)
    execute_test_case(arg1)
Run Code Online (Sandbox Code Playgroud)

您可以编写另一个测试,而不是按照arg2您的建议添加参数化标记,但是,由于 arg2 只有一个值,因此不需要对其进行参数化:

@pytest.mark.parametrize('name, arg1', [
        ('test_1', 1),
        ...
        ('test_100', 100),
])
def test_mine1(name, arg1):
         execute_test_case(arg1)


def test_mine2(name):
         execute_test_case(arg1, arg2)
Run Code Online (Sandbox Code Playgroud)

请注意,第二个测试中的名称固定装置没有值,因为第一个测试中没有使用它(更多内容请参见下文)。

现在,您的代码存在一些不一致之处:

  1. my_setup未使用该夹具。您应该添加该autouse=True选项或将其添加到测试签名中。
  2. 您没有name在测试中使用该参数。
  3. name参数是测试 ID吗?然后,您可以使用id参数化标记上的选项(更多信息请参见此处)。

因此,根据您的需求和我看到的问题,我将重构您的测试,如下所示:

names_list = ['test_1' ... 'test_100']
arg1_list = [1 ... 100]

@pytest.mark.parametrize('arg1', arg1_list, ids=names_list)
def test_mine1(arg1):
         execute_test_case(arg1)


def test_mine2():
         execute_test_case(arg1, arg2)
Run Code Online (Sandbox Code Playgroud)