我如何以编程方式(动态)生成测试,并使用pytest在一系列任意参数上运行它们?

问题描述 投票:0回答:1

我有一个项目,正在测试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却没有回答。

python pytest fixtures
1个回答
0
投票

只需在模块级别读取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"}
]
© www.soinside.com 2019 - 2024. All rights reserved.