使用接受参数的多个夹具进行参数化测试

时间:2018-09-13 05:43:00

标签: python python-3.x pytest

我正在尝试测试我编写的数学函数。我想通过许多不同的装置为它提供数据。问题是所有灯具都接受它们自己的不同灯具参数。

我运行的测试始终是相同的(示例中为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问题。

1 个答案:

答案 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)
相关问题