【问题标题】:Passing pytest fixture in parametrize在参数化中传递 pytest 夹具
【发布时间】:2020-12-14 15:17:55
【问题描述】:

通过在@pytest.mark.parametrize 中传递我在conftest.py 中定义的夹具,我遇到了以下错误:

pytest --alist="0220,0221" test_1.py -v -s
NameError: name 'alist' is not defined

conftest.py:

def pytest_addoption(parser):
    parser.addoption("--alist", action="store")

@pytest.fixture
def alist(request):
    return request.config.getoption("--alist").split(",")

test_1.py:

@pytest.mark.parametrize("channel", alist, scope="class")
class TestRaIntegrationReplay:

    def test_ra_start_time(self, channel):
        print(channel)

如果我将 alist 作为夹具传递给测试,例如:

    def test_ra_start_time(self, alist):
        for channel in alist:
            print(channel)

它运行良好,但它不适用于传递给@pytest.mark.parametrize

【问题讨论】:

  • 前段时间我回答了similar question,应该也适用于您的情况,例如在pytest_generate_tests 中进行参数化,因为您不能直接将夹具传递给mark.parametrize
  • @MrBeanBremen 谢谢,我设法通过修改 conftest.py 中的“pytest_generate_tests”钩子来应用您的第一个解决方案并且它有效,但我现在有另一个问题:有没有办法将 alist 固定装置应用于所有在课堂上进行测试以避免将“alist”夹具传递给每个测试?或者有一种方法可以修改 pytest_generate_tests 以在夹具 alist 应用于类的情况下应用钩子?
  • 我不确定我是否理解:您一般不想使用夹具,还是只想在需要的地方使用它? if "alist" in metafunc.fixturenames 部分已经涵盖了第二种情况。
  • 我会把它放在一个答案中,以澄清创建重复的风险......这样会更容易讨论。

标签: python parameter-passing pytest fixtures


【解决方案1】:

正如评论中提到的,您不能直接将夹具传递给 mark.parametrize 装饰器,因为装饰器是在加载时评估的。
您可以在运行时进行参数化,而不是通过实现pytest_generate_tests

import pytest

@pytest.hookimpl
def pytest_generate_tests(metafunc):
    if "alist" in metafunc.fixturenames:
        values = metafunc.config.option.alist
        if value is not None:
            metafunc.parametrize("alist", value.split(","))

def test_ra_start_time(alist):
    for channel in alist:
        print(channel)

def test_something_else():
    # will not be parametrized
    pass

参数化是根据测试函数中alist 参数的存在来完成的。要使参数化起作用,需要此参数(否则您会因为缺少参数而出错)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多