我有一个包含几个JSON文件的AWS S3目录,这些文件用作测试输入。
我创建了一个PyTest模块,该模块使用模块级fixture
下载一次所有的JSON文件,然后运行多个测试函数-每个函数都通过JSON集进行参数化:
import pytest
import os
from tempfile import mkdtemp, TemporaryDirectory
from glob import glob
JSONS_AWS_PATH = 's3://some/path/'
def download_jsons():
temp_dir = mkdtemp()
aws_sync_dir(JSONS_AWS_PATH, temp_dir)
json_filenames = glob(os.path.join(local_path, "*.json"))
return json_filenames
@pytest.fixture(scope='module', params=download_jsons()) #<-- Invoking download_jsons() directly
def json_file(request):
return request.param
def test_something(json_file):
# Open the json file and test something
def test_something_else(json_file):
# Open the json file and test something else
def test_another_thing(json_file):
# you got the point...
该测试模块本身可以工作-唯一的痛点是如何在模块\会话末尾清除temp_dir
。
由于download_jsons()
是直接被调用的,因此json_file
固定装置甚至没有启动之前-它没有自己的上下文。因此,在完成所有测试后,我无法使其干净temp_dir
。
我想将download_jsons()
本身作为模块\会话范围fixture
。像这样:
fixture(scope='module')
def download_jsons():
temp_dir = mkdtemp()
# Download and as glob, as above
yield json_filenames
shutil.rmtree(temp_dir)
或
fixture(scope='module')
def download_jsons(tmpdir_factory):
#...
如@Gabriela Melo所建议。
问题是如何使json_file
返回的列表中的download_jsons()
灯具参数化,而又不直接调用它呢?
我尝试使用mark.parametrize
,setup_module()
或pytest_generate_tests(metafunc)
来实现此解决方案-但无法实现我一直在寻找的确切功能。
答案 0 :(得分:0)
这似乎是您要寻找的:https://docs.pytest.org/en/latest/tmpdir.html#the-tmpdir-factory-fixture
(使用Pytest的tmpdir_factory
固定装置,并将json_file
函数的范围设置为session
而不是module
)
答案 1 :(得分:0)
如果您想使用资源进行参数化,固定装置将无法返回该资源(至少对于当前版本的pytest
而言)。但是,您可以将设置/拆卸代码移到挂钩中-这还将通过pytest_generate_tests
挂钩启用参数化。示例:在项目的根目录中,创建一个名为conftest.py
的文件,其内容如下:
from tempfile import TemporaryDirectory
from pathlib import Path
def pytest_sessionstart(session):
# this is where we create the temp dir and download the files
session.config._tempdir = TemporaryDirectory()
d = session.config._tempdir.name
aws_sync_dir(JSONS_BLOBBY_PATH, d)
session.config._json_files = Path(d).glob("*.json")
def pytest_sessionfinish(session):
# this is where we delete the created temp dir
session.config._tempdir.cleanup()
def pytest_generate_tests(metafunc):
if "file" in metafunc.fixturenames:
# parametrize the file argument with the downloaded files
files = metafunc.config._json_files
metafunc.parametrize("file", files)
您现在可以像往常一样在测试中使用file
参数,例如
def test_ends_with_json(file):
assert file.suffix == ".json"