我正在尝试使用@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
我在类作用域fixture中创建数据,然后将其用作test_data
的参数集。我期望test_data
运行两次,分别使用参数1, 2
和3, 4
。然而,我得到的是一个带有参数1, 2
和以下stdout的单个测试:
1 2
[('1', '2'), ('3', '4')]
data
的值显然是[('1', '2'), ('3', '4')]
,这意味着类范围的fixture按照我的意愿初始化了它。但不知何故,参数化似乎在此之前就已经发生了。
有没有更干净的方法来实现我想要的?我可以简单地在test_data
方法中运行一个循环,但我觉得这违背了参数化的目的。
有没有办法在make_data
夹具中返回data
并在@pytest.mark.parametrize
中使用夹具?当使用@pytest.mark.parametrize("arg0, arg1", make_data)
时,我得到了TypeError: 'function' object is not iterable
。make_data
必须是一个fixture,因为在实际的测试用例中它依赖于其他fixture。
我是pytest的新手,如果有任何提示,我将不胜感激。非常感谢。
编辑
为了解释我为什么要做我正在做的事情:按照我的理解,@pytest.mark.parametrize("arg0, arg1", data)
允许使用硬编码的data
集进行参数化。如果我的测试数据不是硬编码的呢?如果我需要预处理它,就像我在make_data
方法中尝试的那样,该怎么办?具体来说,如果我需要从文件或url中读取它,该怎么办?假设我有1000个数据样本要运行测试用例,如何对它们进行硬编码?
我可以以某种方式使用函数在@pytest.mark.parametrize("arg0, arg1", data)
中生成data
参数吗?类似于:
def obtain_data():
data = []
# read 1000 samples
# pre-process
return data
@pytest.mark.parametrize("arg0, arg1", obtain_data())
这会产生一个错误。
事实证明,pytest案例提供了定义函数参数化案例的选项,这对我们有很大帮助。希望这能帮助每个正在寻找类似的人