首先我们要了解什么是参数化。在编写测试用例时,有时需要针对不同的输入预期得到不同的输出。这种情况下,我们就需要在一个测试函数中多次调用,并给出不同的参数。使用参数化就是一种更简洁明了的方式,它允许我们使用一组数据来自动生成一组测试用例。
pytest提供了一个decorator——@pytest.mark.parametrize()来实现这个功能。下面我将为大家演示如何使用这个工具。
假设我们需要测试一个计算器函数add(),这个函数可以接受两个参数,返回这两个参数的和。我们可以分别输入不同的参数,然后检查它是否按照我们期望的那样工作。下面是一个示例代码:
import pytest
def add(x, y):
return x + y
@pytest.mark.parametrize("input1, input2, expected", [
(2, 3, 5),
(3, 4, 7),
(0, 0, 0),
(-1, 1, 0),
(100, -100, 0)
])
def test_add(input1, input2, expected):
assert add(input1, input2) == expected
这段代码首先定义了一个函数add(),然后使用@pytest.mark.parametrize()来参数化test_add()这个测试用例。这个decorator接受两个参数:第一个参数是一个字符串,指定了要传递给测试用例的一个或多个参数的名称;第二个参数是一个可迭代的列表,包含了一组参数组合,每个参数组合是一个元组。
这个示例中,我们提供了一个包含5个元组的列表。每个元组表示一个参数组合,分别代表了input1、input2和expected的值。在执行test_add()测试用例时,pytest将循环遍历这个列表,并将每个参数组合赋值给input1、input2和expected。
例如,第一次循环时,input1将被赋值为2,input2将被赋值为3,expected将被赋值为5。然后调用add(input1, input2)函数,检查其是否等于expected。
另一个示例是在测试计算器函数时,我们还需要测试除法函数。这个函数需要测试0作为被除数的情况。这里我使用了两个fixture,一个用来获取被除数,一个用来获取除数。代码如下:
import pytest
def add(x, y):
return x + y
def div(x, y):
return x / y
@pytest.fixture(params=[4, 0, -4])
def num(request):
return request.param
@pytest.fixture(params=[2, -2])
def denom(request):
return request.param
@pytest.mark.parametrize("func, input1, input2, expected", [
(add, 2, 3, 5),
(add, 3, 4, 7),
(add, 0, 0, 0),
(add, -1, 1, 0),
(add, 100, -100, 0),
(div, 10, 2, 5),
(div, 10, -2, -5),
(div, 0, 2, 0),
(div, 0, -2, 0),
(div, 30, 4, 7.5),
(div, 30, -4, -7.5),
(div, 35, 5, 7),
(div, 35, -5, -7),
(div, num, denom, num/denom)
])
def test(func, input1, input2, expected):
assert func(input1, input2) == expected
在这个示例中,我们定义了两个fixture,一个用来获取被除数num,一个用来获取除数denom。为了测试0作为被除数的情况,我们将0添加到了num的参数列表中。在test()测试用例中,我们将add()和div()函数都作为参数进行了测试,而且测试了num和denom的组合。这样,我们就可以在测试除法函数时覆盖到除数为0的情况。