在参数化的夹具中缓存测试数据
Posted
技术标签:
【中文标题】在参数化的夹具中缓存测试数据【英文标题】:Caching test data in parameterized fixtures 【发布时间】:2021-12-08 09:10:18 【问题描述】:我有各种使用通用数据的测试用例。我使用pytest
夹具来缓存测试数据并加快测试速度。
例如:
@pytest.fixture(scope='module')
def data():
large_data = download('XYZ')
return large_data
def test_foo(data):
pass
def test_bar(data):
pass
我想将测试扩展到两个数据集。蛮力解决方案是:
@pytest.fixture(scope='module')
def data1():
large_data = download('XYZ')
return large_data
@pytest.fixture(scope='module')
def data2():
large_data = download('ABC')
return large_data
def test_foo1(data1):
pass
def test_foo2(data2):
pass
def test_bar1(data1):
pass
def test_bar2(data2):
pass
现在的问题是test_bar
是通用的。从某种意义上说,测试程序独立于数据。因此,复制它是一个坏主意。
所以,我决定使用间接参数如下:
@pytest.fixture(scope='module')
def data(request):
if request.param == 1:
large_data = download('XYZ')
if request.param == 2:
large_data = download('ABC')
return large_data
@pytest.mark.parametrize('data', [1], indirect=True)
def test_foo1(data):
pass
@pytest.mark.parametrize('data', [2], indirect=True)
def test_foo2(data):
pass
@pytest.mark.parametrize('data', [1, 2], indirect=True)
def test_bar(data):
pass
但现在我失去了缓存优势。下载数据以供测试。如何告诉 pytest 缓存参数化夹具的数据?
【问题讨论】:
问题显然出在测试顺序上——因为fixture是用不同的参数调用的,它不能在模块中只调用一次,因为它通常是使用模块范围的fixture来完成的。最好的选择可能是缓存数据并在下次访问时重复使用。 【参考方案1】:我找到了一个(非理想的)解决方案。这个想法是为每个测试数据定义一个固定装置(不能很好地扩展),然后使用“包装器”参数化固定装置来返回它们的值。
@pytest.fixture(scope='module')
def data1():
large_data = download('XYZ')
return large_data
@pytest.fixture(scope='module')
def data2():
large_data = download('ABC')
return large_data
@pytest.fixture(scope='module')
def data(request):
return request.getfixturevalue(request.param)
def test_foo1(data1):
pass
def test_foo2(data2):
pass
@pytest.mark.parametrize('data', ['data1', 'data2'], indirect=True)
def test_bar(data):
pass
我已经验证过(至少在这个例子中)每个数据集都被下载了一次,并且只下载了一次。不过,我很想知道是否有“更清洁”的解决方案。
【讨论】:
以上是关于在参数化的夹具中缓存测试数据的主要内容,如果未能解决你的问题,请参考以下文章