如何使用pytest为classscope fixture创建工厂?

2024-04-19 13:41:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一组fixture,它们都做同样的事情,打开一个json文件并使它对测试类可用。你知道吗

@pytest.fixture(scope="class")
def category_params(request):
    base_path = os.path.abspath(..)
    path = os.path.join(base_path, "data/category_params.json")
    with open(path, "r") as fp:
        category_params = json.load(f)
    return category_params

我为测试域中的所有不同测试类别重复此设置。似乎我应该为它编写一个函数,但我不确定如何使用pytest来实现它。我想我应该问问如何创建一个fixture工厂,这是一个pytest fixture对象,它可以创建其他fixture对象。你知道吗


Tags: 文件path对象jsonbasepytestosrequest
2条回答

(警告:我没有测试此代码。)

我认为这样的事情应该管用。你知道吗

def make_fixture_for(data_file):
    @pytest.fixture(scope="class")
    def params_fixture(request):
        base_path = os.path.abspath(..)
        path = os.path.join(base_path, data_file)
        with open(path, "r") as fp:
            return json.load(fp)
    return params_fixture

foo_params = make_fixture_for("data/foo.json")
bar_params = make_fixture_for("data/bar.json")

这在模块的顶层定义了fixture函数,pytest需要它们, 但它是以一种紧凑的方式实现的。你知道吗

这可以在数据文件名的一个循环中完成,并使用globals将它们放入模块的顶级上下文中,但这感觉就像是不可逾越的魔法。上面的代码非常简单。你知道吗

也许pytest不喜欢很多fixture函数在内部具有相同的名称;那么在函数上设置.__name__可能会有帮助,也可能没有;同样,我没有测试这段代码,而且我不记得pytest的fixture discovery过程的细节。你知道吗

您可以parametrize your fixture函数,这意味着每个测试可以给它一个不同的JSON文件来加载:

import pytest
import os
import json


@pytest.fixture(scope="class")
def json_content(request):
    base_path = os.path.abspath(..)
    path = os.path.join(base_path, request.param)

    with open(path, "r") as fp:
        data = json.load(fp)

    return data


@pytest.mark.parametrize("json_content", ["abc.json"], indirect=True)
def test_a(json_content):
    print(json_content)


@pytest.mark.parametrize("json_content", ["xyz.json"], indirect=True)
def test_b(json_content):
    print(json_content)

注意:测试示例没有显示每个类使用相同的fixture,但这不是演示参数化所必需的。你知道吗

相关问题 更多 >