什么是数据驱动的参数化测试?

“参数化,就是将测试数据提取出来,与逻辑分离,通过参数传递不同的测试数据来驱动用例运行,又称为数据驱动测试(Data-Drive test,简写ddt)。”

@pytest.mark.parametrize是pytest提供的参数化测试辅助工具。使用方法非常简单,主要有两个函数参数: 第一个函数参数是字符串形式的测试数据名称,第二个函数参数是列表形式的测试数据集合。测试方法的参数列表中需要传入对应的测试数据名称,然后就可以在测试方法内部使用参数化的测试数据了。如果每组测试数据由多个数据构成,则第一个函数参数中用逗号隔开测试数据名称,第二个函数参数的列表中每组测试数据都是元组。

示范如下: image.png 如图,测试数据有两个字段,三组数据。测试函数检验每个input_str是否是target_str的子字符串。测试函数的参数就是对应的字段名称。运行这个测试,可以看到,test_includes被执行了三次: image.png


像上面这个例子中,我们的测试数据集合是直接写在测试代码里的,这样并不好。为了做数据驱动的参数化测试,我们需要把测试数据集合从代码中提取出来。比如,我们可以提取到外部文件中,然后在测试代码中读取外部文件就可以了。例子如下: image.png image.png

注意,我们的read_data是一个生成器,其中用了关键字yield,也就是说这个方法每次被调用都会生成一组测试数据。那么@pytest.mark.parametrize会把这个方法生成的每组测试数据分配给input_str和target_str,在每次测试中使用。


在上一篇文章中我讲过fixture可以和pytest.mark.parametrize联合使用做参数化测试。这个怎么用呢?比如,上面这个例子中,如果我们想要对于读取的测试数据进行处理,比如我们想要给测试数据去除收尾的空白符。 image.png

在上图中,因为pytest.mark.parametrize加上了indirect=True, 所以read_data()得到的每组测试数据没有直接传给测试函数,而是先传给了processedData这一fixture,由其request.param来接收。fixture中把每条测试数据拆开,对于每个元素分别去除首位的空白符,最后组装成一个整个元组返回给测试函数。测试函数引用了这个fixture,将其返回值拆开成需要的测试数据后使用。

在上图的代码中,我们结合使用了pytest.mark.parametrize和pytest.fixture,实现了测试数据的读取、处理和使用的分离(分成了三块)。其中read_data和processedData是可以在不同的测试函数中复用的。