我在同一文件中有许多测试函数,它们共享一组通用的参数化参数,如下面的代码片段所示。当测试功能的数量增加(> 100)时,为每个测试功能重复这些参数似乎并不有效,并且容易出错。 pytest中有什么方法可以定义一组通用的参数化参数并在所有测试中共享?夹具用于注入公共数据依赖项。我想知道是否有任何类似的工具可以注入常见的 arguments 。
import pytest
@pytest.mark.parametrize('common_arg1', [0, 1])
@pytest.mark.parametrize('common_arg2', [2, 3])
@pytest.mark.parametrize('a', [0, 1])
def test_1(common_arg1, common_arg2, a):
pass
@pytest.mark.parametrize('common_arg1', [0, 1]) # repetition
@pytest.mark.parametrize('common_arg2', [2, 3]) # repetition
@pytest.mark.parametrize('b', [0, 1])
def test_2(common_arg1, common_arg2, b):
pass
...
@pytest.mark.parametrize('common_arg1', [0, 1]) # more repetition!
@pytest.mark.parametrize('common_arg2', [2, 3]) # more repetition!
@pytest.mark.parametrize('x', [0, 1])
def test_100(common_arg1, common_arg2, x):
pass
答案 0 :(得分:2)
您可以将所有测试用例移到一个帮助器类中,并将通用装饰器放在该类的顶部。某些测试(方法)专用的装饰器可以直接应用于它们。请查看下面的示例。
import pytest
@pytest.mark.parametrize('common_arg1', [0, 1])
@pytest.mark.parametrize('common_arg2', [2, 3])
class TestParametrized:
@pytest.mark.parametrize('a', [0, 1])
def test_1(self, common_arg1, common_arg2, a):
pass
@pytest.mark.parametrize('b', [0, 1])
def test_2(self, common_arg1, common_arg2, b):
pass
@pytest.mark.parametrize('x', [0, 1])
def test_100(self, common_arg1, common_arg2, x):
pass
答案 1 :(得分:1)
正如Kammil指出的那样,最好的方法是拥有一个Test类,作为Kammil方法的替代方法,是在您的测试数据中拥有一个class属性,通过这种方式,您可以拥有不使用common_arg1的测试方法。和class中的common_arg2。但是,您仍然需要标记测试,但不需要重写所有参数化参数,并且如果您从class属性更改值,那么它将反映在所有测试中。
如果要在同一类中使用不需要common_arg1和common_arg2的测试方法,这将特别有用。
请记住,如果您装饰类,则所有方法都必须具有common_arg1和common_arg2作为参数,如果您尝试编写一个不在方法的args列表中引用它们的方法,则将得到一个{{1} }错误。
为避免这种情况,您可以执行以下操作:
function uses no argument 'common_arg1'
请注意,test_1000将成功执行,并且不会抱怨没有提到common_args1和common_args2。您还可以通过编写两个类属性将common_args拆分为2。
答案 2 :(得分:0)
另一种方法是使用参数化的 pytest
固定装置。对于单个参数化,很容易使用普通的 pytest
:
import pytest
@pytest.fixture(params=[0, 1])
def common_arg1(request):
return request.param
@pytest.fixture(params=[2, 3])
def common_arg2(request):
return request.param
@pytest.mark.parametrize('a', [0, 1])
def test_1(common_arg1, common_arg2, a):
pass
@pytest.mark.parametrize('b', [0, 1])
def test_2(common_arg1, common_arg2, b):
pass
@pytest.mark.parametrize('x', [0, 1])
def test_100(common_arg1, common_arg2, x):
pass
如果您希望以更紧凑的方式编写此代码,可以使用 pytest_cases.param_fixture
:
from pytest_cases import param_fixture
common_arg1 = param_fixture('common_arg1', [0, 1])
common_arg2 = param_fixture('common_arg2', [2, 3])
对于多个参数化,您可能希望使用 @pytest_cases.fixture
以便能够使用 @pytest.mark.parametrize
:
import pytest
from pytest_cases import fixture
@fixture
@pytest.mark.parametrize('a', [0, 1])
@pytest.mark.parametrize('b', [2, 3])
def common_arg_multiple(a, b):
return a * b, a - b
有关详细信息,请参阅 pytest-cases documentation。 (我是作者;))