参数化是指在测试的过程中,相同的测试步骤但不同的测试场景需要使用不同的测试数据,这个过程可以使用参数化的思想来完成。参数化的核心思想是把测试数据分离到一个列表中,这样分离到列表中的测试数据就是列表中具体的元素,在执行的过程中,循环列表中的对象依次赋值即可。
在pytest测试框架中,可以通过parametrize来实现参数化的测试。例如,被测函数的逻辑是两个数相加,下面以该函数为例演示参数化案例的实战。依据参数化的核心思想,不管是什么数据类型,只要存储在列表中就循环对象进行赋值。下面详细演示不同的数据形式并将测试数据分离到不同的文件形式。
列表数据形式是指测试的数据存储在列表中的元素数据类型是列表,代码如下。
备注:
如上代码中,测试数据被分离到函数data()中,分离的数据是列表的数据类型。在测试函数test_add_list()中,测试函数的形式参数需要与@pytest.mark.parametrize中的一致,这样函数data()在每次循环时,都会依据列表中的元素信息进行赋值。第一次循环时形式参数a赋予的值是1,第二次循环时a赋予的值是字符串wuya,第三次循环时a赋予的值是1.0,测试函数中形式参数b在循时赋予的值分别是1、Share、1.0。执行如上代码后,执行结果如图1-15所示。
图1-15 列表数据形式的执行结果
元组数据形式是指分离出来的测试数据在列表中的数据类型是元组,具体分离的测试数据和代码如下。
备注:
如上源代码中,从data()函数中分离的测试数据是元组的数据类型,列表循环时会对元组中的值一一进行赋值,执行代码后的输出结果如图1-16所示。
图1-16 元组数据形式执行结果
字典数据形式是指分离的测试数据的数据类型是字典,其测试数据以及测试代码如下。
备注:
如上代码中,从data()函数中分离出来的测试数据的数据类型都是字典,字典数据类型的特点是key-value的数据形式。在测试函数执行的过程中,依据字典的key值可以循环获取value的值。执行代码后的输出结果如图1-17所示。
图1-17 字典数据形式执行结果
在测试的过程中,也可以把测试数据分离到JSON等文件中,这个过程叫数据驱动。这里以JSON文件为案例,把测试数据分离到JSON文件中,JSON文件的内容如下。
备注:
如上是分离到JSON文件的测试数据。在JSON文件中,特别需要注意的是,JSON文件中的字符串必须用双引号并且是key-value的数据形式。
如上已将数据分离到JSON文件中,下面详细演示从JSON文件中读取数据并与pytest测试框架的参数化整合起来,代码如下。
备注:
如上代码中,readJson()函数是从JSON文件中读取测试数据并且发现数据是列表的数据形式。执行如上的代码后输出的结果如图1-18所示。
图1-18 JSON文件形式执行结果
在数据驱动中,YAML文件也是被广泛使用的文件之一,下面介绍如何把测试数据分离到YAML文件中,YAML文件的内容如下。
在Python中,操作YAML文件需要单独安装第三方库,安装命令如下。
pip3 install pyyaml
安装成功后,下面详细介绍从YAML文件中读取数据,并与pytest测试框架整合起来应用于参数化,代码如下。
备注:
如上代码中,函数readYaml()读取YAML文件后以列表的形式返回数据。执行如上代码后,输出的结果如图1-19所示。
图1-19 YAML文件形式执行结果
在API自动化测试中,很多测试人员使用的是测试工具PostMan,但是后期代码迁移过程的成本又很高。结合参数化的本质,其实可以很智能化地实现把PostMan中的API测试用例转为pytest测试代码。被测试的登录服务源码如下。
针对如上的登录微服务代码,PostMan中的接口测试用例如图1-20所示。
图1-20 PostMan中接口测试用例
把login集合导出为JSON文件,分析JSON文件后,发现请求的信息都在request中,那么可以手动把响应数据添加到response中,完善后的JSON文件内容如下。
下面读取JSON文件,结合参数化的思想智能化地把PostMan的测试用例转为pytest代码,代码如下。
备注:
如上代码中,在函数readPostMan()中,将JSON文件中的数据解析出来后处理成了列表的数据类型。下面再和pytest的参数化整合起来,就可以实现把PostMan的测试用例智能化地转为pytest测试代码,代码执行后的结果如图1-21所示。
图1-21 PostMan的测试用例智能化地转为pytest测试代码的执行结果
在微服务架构下,有众多的服务需要进行单接口测试,以保障服务在参数为空以及请求参数错误的情况下后端服务的处理逻辑正常。如果使用常规编写API测试用例的方式,那么只会编写很多重复性的代码。结合参数化的思想,可以把请求地址、请求参数、响应数据分离出来,这样做的优势是编写一个测试用例的代码就能批量执行以及覆盖所有的测试场景。以本节的“6.PostMan智能化转为pytest测试代码”的登录微服务为案例,下面使用参数化的特性实现登录微服务批量化的验证和测试场景的覆盖,实现代码如下。
如上代码中,把测试数据分离到data()函数,分离出的测试数据主要是请求地址、请求参数、响应数据,执行如上代码后,输出结果如下。
通过以上结果发现,批量化验证微服务的执行结果都成功了。这样可以使用更少的代码实现最大的覆盖率。
在pytest参数化中也会使用pytest内置的固件request,通过request.param可以获取参数。下面以add()函数为例介绍这部分的应用,代码如下。
备注:
如上代码中,编写了fixture的函数param(),在该函数中通过request.param获取测试数据。在测试函数中形式参数param其实本质上是fixture的函数param()的对象。执行如上代码后,输出的结果如图1-22所示。
图1-22 基于request参数化执行结果