我正在尝试测试我编写的数学函数。我想通过许多不同的装置为它提供数据。问题是所有灯具都接受它们自己的不同灯具参数。
我运行的测试始终是相同的(示例中为test_myfunc
),并且我要插入的灯具都具有相同的兼容返回值(clean_data
和{{1 }})。因此,我想将这两个装置“链接”在一起,以便一个或另一个为测试提供输入。
设置如下:
noisy_data
我使用这么多夹具的原因是我想运行完整的测试矩阵,并且能够随意启用,禁用,xfail等。
由于import numpy as np
import pytest
from scipy import stats
def myfunc(x, y):
return True
_noises = {
'normal': lambda scale, n: np.random.normal(scale=scale, size=n),
'uniform': lambda scale, n: np.random.uniform(-scale, scale, size=n),
'triangle': lambda scale, n: np.random.triangular(-scale, 0, scale, size=n),
}
@pytest.fixture(params=[10**x for x in range(1, 4)])
def x_data(request):
""" Run the test on a few different densities """
return np.linspace(-10, 10, request.param)
@pytest.fixture(params=[0, 1, 0xABCD, 0x1234])
def random_seed(request):
""" Run the test for a bunch of datasets, but reporoducibly """
np.random.seed(request.param)
@pytest.fixture(params=np.arange(0.5, 5.5, 0.5))
def shape(request):
""" Run the test with a bunch of different curve shapes """
return request.param
@pytest.fixture()
def clean_data(x_data, shape):
""" Get a datset with no noise """
return shape, stats.gamma.pdf(x_data, shape)
@pytest.fixture(params=["triangle", "uniform", "normal"])
def noisy_data(request, clean_data, random_seed):
shape, base = clean_data
noise = _noises[request.param](10, base.shape)
return shape, base + noise
def test_myfunc(x_data, data):
shape, y_data = data
assert myfunc(x_data, y_data)
和clean_data
固定装置返回相同类型的结果,因此我希望能够一次接一个地使用它们两者进行测试。如何使用包含参数的多个夹具运行单个测试?
如果可能的话,我想避免测试的产生。我熟悉间接参数化测试的想法,例如在Running the same test on two different fixtures中。我试图创建一个可以按名称执行y数据提供程序的元设备:
noisy_data
当我运行测试时
@pytest.fixture()
def data(request):
""" Get the appropriate datset based on the request """
return request.getfuncargvalue(request.param)
@pytest.mark.parametrize('data', ['clean_data', 'noisy_data'], indirect=True)
def test_myfunc(x_data, data):
shape, y_data = data
assert myfunc(x_data, y_data)
我遇到了很多错误,所有这些似乎都指向以下事实:间接夹具需要参数,而这些参数并未提供:
pytest -v pytest-parametrized.py
如果以某种方式提供缺少的参数是很好的答案,但是我不想这样问问题,因为我认为我可能在这里遇到了一个巨大的XY问题。
答案 0 :(得分:2)
pytest
不支持将灯具作为参数标记中的参数传递。有关更多详细信息,请参见问题#349:Using fixtures in pytest.mark.parametrize。当需要使用夹具进行参数化时,我通常求助于创建一个接受所有参数夹具的辅助夹具,然后在测试中间接进行参数化。这样,您的示例将变为:
@pytest.fixture
def data(request, clean_data, noisy_data):
type = request.param
if type == 'clean':
return clean_data
elif type == 'noisy':
return noisy_data
else:
raise ValueError('unknown type')
@pytest.mark.parametrize('data', ['clean', 'noisy'], indirect=True)
def test_myfunc(x_data, data):
shape, y_data = data
assert myfunc(x_data, y_data)