我有一个项目,正在测试API处理某些查询的能力。我想基于JSON输入文件以编程方式生成唯一的测试用例。因此,到目前为止,我所做的是:
# Open the JSON file with all test data:
@pytest.fixture(scope="class")
def test_data(request):
base_path = os.path.abspath(os.path.dirname(__file__))
path = os.path.join(base_path, request.file_name)
with open(path, "r") as f:
test_data = json.load(f)
return test_data
接下来,我在测试班级中使用此数据:
@pytest.mark.parametrize("test_data", ["filename"], indirect=True)
def use_all_testdata(self, test_data):
for t_dict in test_data:
# What do I do here?
我能够逐行访问json文件,但我不知道如何使用它来以编程方式生成pytest测试。如果需要,我希望能够以这种方式运行一百个测试。我已经看到此问题针对单元测试回答了,但对于pytest却没有回答。
只需在模块级别读取JSON文件,然后对读取的数据进行参数化:
base_path = os.path.abspath(os.path.dirname(__file__))
path = os.path.join(base_path, "file.json")
with open(path, "r") as f:
test_data = json.load(f)
@pytest.mark.parametrize("data", test_data, ids=repr)
def test_json(data):
assert data is not None
如果有多个文件,请在循环中读取它们,例如
files = ["file1.json", "file2.json"]
test_data = []
base_path = os.path.abspath(os.path.dirname(__file__))
for filename in files:
path = os.path.join(base_path, filename)
with open(path, "r") as f:
test_data.extend(json.load(f))
您还可以实现pytest_generate_tests
挂钩。这种方法的优点是,如果有很多测试,则不必将pytest_generate_tests
装饰器复制到每个测试中:
parametrize
只需在测试中使用def pytest_generate_tests(metafunc):
base_path = os.path.abspath(os.path.dirname(__file__))
path = os.path.join(base_path, "file.json")
with open(path, "r") as f:
test_data = json.load(f)
metafunc.parametrize("data", test_data, ids=repr)
def test_json(data):
assert data is not None
def test_another_json(data):
assert "foo" in data.keys()
作为参数,它将由metafunc参数化。
示例:包含data
的
file.json
产量测试:
[
{"foo": "bar"},
{"foo": "baz"},
{"spam": "eggs"}
]