【问题标题】:pytest parametrize global variable as argumentpytest 将全局变量参数化为参数
【发布时间】:2022-11-04 02:35:15
【问题描述】:

我正在尝试使用@pytest.mark.parametrize 对一系列参数运行相同的测试。测试数据必须动态计算,我尝试如下:

data = [("1", "2")]

@pytest.fixture(scope="class")
def make_data():
    global data

    data.append(("3", "4"))

@pytest.mark.usefixtures("make_data")
class Tester:

    @pytest.mark.parametrize("arg0, arg1", data)
    def test_data(self, arg0, arg1):
        print(arg0, arg1)
        print(data)
        assert 0

我在类范围夹具中创建数据,然后将其用作test_data 的参数集。我希望test_data 运行两次,参数分别为1, 2 和3, 4。但是,我得到的是带有参数1, 2 和以下标准输出的单个测试:

1 2
[('1', '2'), ('3', '4')]

data 的值显然是[('1', '2'), ('3', '4')],这意味着类作用域夹具按照我的意愿对其进行了初始化。但不知何故,参数化似乎在此之前就已经发生了。

有没有更清洁的方法来实现我想要的?我可以简单地在test_data 方法中运行一个循环,但我觉得这违背了参数化的目的。

有没有办法在make_data 夹具中返回data 并使用@pytest.mark.parametrize 中的夹具?使用@pytest.mark.parametrize("arg0, arg1", make_data) 时,我得到TypeError: 'function' object is not iterable。 make_data 必须是一个夹具,因为在真实的测试用例中它依赖于其他夹具。

我是 pytest 的新手,如果有任何提示,我将不胜感激。谢谢你。

【问题讨论】:

  • 在 unittest 中引入全局变量并不是一个好主意。您应该使用“setup_method 函数”设置您测试的设置,并使用“teardown_method 函数”进行清理。当测试函数中有更复杂的参数时(例如带有状态的类),您应该使用 pytest.fixture。但绝不是全局变量
  • 这段代码有几个问题,@PicxyB 指出其中之一。你能提供更多关于你在这个测试中想要达到的目标的信息吗?并展开数据的来源是什么(例如可以有两个函数,一个生成("1", "2"),另一个生成("3", "4"))?

标签: pytest parametrized-testing


【解决方案1】:

直接的方法是使用 pytest 全局变量:

您可以在conftest.py 中分配它们:

def pytest_configure(config):
    pytest.data = foo()

并且在测试用例中

@pytest.mark.parametrize("data", pytest.data)
def test_000():
    ...

但我同意之前的评论,这不是最佳做法

【讨论】:

    猜你喜欢
    • 2017-07-31
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2023-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多