【问题标题】:pytest.mark.parametrize does not work as expected with pytest.lazy_fixturepytest.mark.parametrize 不能按预期使用 pytest.lazy_fixture
【发布时间】:2020-06-14 16:17:23
【问题描述】:

我对以下代码有问题——最终结果与预期不符:

env.yaml

config:
  requestenv: [test, uat]
  envinfo:
    test: [{imp: 111, clk: 111, "act": 111}, {imp: 222, clk: 222, act: 222}]
    uat: [{ imp: 333, clk: 333, act: 333 }, { imp: 444, clk: 444, act: 444 }]

test_env.py

import pytest
from utils import configutil

configpath = r".\monitor.request.config.yaml"

config = configutil.readyamlconfig(configpath)


requestenv = config["config"]["requestenv"]


@pytest.fixture(scope="function", params=requestenv)
def one(request):
    env = request.param
    return config["config"]["envinfo"][request.param]


@pytest.mark.parametrize("testdata", [pytest.lazy_fixture("one")])
def test_func01(testdata):
    print()
    print("*" * 10)
    print(testdata)

测试数据总是带有env.yaml 配置文件,并且取决于测试环境(在我的例子中是testuat)。我想遍历每个环境和该环境中的每个项目,如下所示运行pytest -s .\test_env.py

[预期]

test_env.py::test_func01[test-{ imp: 111, clk: 111, act: 111 }]
test_env.py::test_func01[test-{ imp: 222, clk: 222, act: 222 }]
test_env.py::test_func01[saas-{ imp: 333, clk: 333, act: 333 }]
test_env.py::test_func01[saas-{ imp: 444, clk: 444, act: 444 }]

[实际]

test_env.py::test_func01[test-[[{imp: 111, clk: 111, "act": 111}, {imp: 222, clk: 222, act: 222}]]]
test_env.py::test_func01[test-[{ imp: 333, clk: 333, act: 333 }, { imp: 444, clk: 444, act: 444 }]]

【问题讨论】:

    标签: python pytest fixtures


    【解决方案1】:

    我还没有看到如何使用lazy-fixture 执行此操作。问题是每个测试环境中的测试数量可能会有所不同,我看不出如何在夹具中反映这一点。如果测试数量相同(如您的示例中),则以下内容将起作用:

    @pytest.fixture(params=requestenv)
    def envs(request):
        yield envinfo[request.param]
    
    @pytest.fixture(params=range(len(envinfo["test"])))
    def data(request, envs):
        yield envs[request.param]
    
    def test_func01(data):
        print(data)
    

    如果数据的长度是可变的,唯一想到的就是使用钩子手动参数化函数:

    def mydata():
        data = []
        ids = []  # not needed, just to make make the test name better readable
        for key in requestenv:
            data.extend([d for d in envinfo[key]])
            ids.extend([key + "-" + str(i) for i in range(len(envinfo[key]))])
        return data, ids
    
    @pytest.hookimpl
    def pytest_generate_tests(metafunc):
        if "testdata" in metafunc.fixturenames:
            data, ids = mydata()
            metafunc.parametrize("testdata", data, ids=ids)
    
    def test_func02(testdata):
        print()
        print(testdata)
    

    两种变体都会产生预期的输出。

    可能我在这里遗漏了一些东西,并且有一个更好的解决方案。

    【讨论】:

    • 抱歉延迟响应,但在您的第一个解决方案中,env 值不应在此处硬编码为“测试”:@pytest.fixture(params=range(len(envinfo["test) "])))
    • 这就是为什么我写了“如果测试的数量相同” - 在这种情况下,您可以在任何环境中获取测试的长度。如果不是这种情况,第一个解决方案将不起作用。
    • 谢谢,那我会采取第二种解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 2015-06-26
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多