注:本节教材内容,与上前三周推送的文章为一个项目实战内容。
回顾上节内容,请点击:
教材连载:蜗牛进销存项目实战(一)
教材连载:利用Requests库完成“蜗牛进销存”的登录功能教材连载:利用Requests库完成“蜗牛进销存”的新增会员与测试
接口测试框架整合
1.框架设计
前面我们只是单独对一个功能进行测试,试想一下:如果会员新增功能的用例用成百上千条,那代码岂不是很多?又比如现在要对会员修改或商品出库的接口进行测试,代码量也要成倍的增加? 数据都直接嵌入到代码中,那维护起来会不会很麻烦?为此,我们需要设计一个相对完善的自动化测试框架来解决这些问题。
关于自动化测试框架,常见的几种解释有:
(1)测试自动化框架就是支撑自动化测试的一系列假设,概念和工具。
(2)自动化测试框架就是一个能够进行自动化测试的程序。
(3)由一个或多个自动化测试基础模块、自动化测试管理模块、自动化测试统计模块等组成的工具集合。
从广泛的角度讲,自动化测试框架以设计思想为指导,包含了测试数据,测试用例脚本,测试工具,支撑组件等一系列集合,并能与管理流程和测试流程相适应。而一套好的测试框架不仅要满足高重用性和高维护性,还要兼顾团队协作等方面。

上图是笔者设计的自动化接口测试框架,主要依靠调度模块来处理整个流程,首先是获取到数据模块的数据,再将数据传给工具模块进行处理,最后将处理后的数据传给执行模块进行测试,并得到执行模块返回的结果。
实际上这个框架借用了数据驱动的思想。数据驱动不是单纯的一种技术,而是一种理念。通过将测试代码和测试数据的分离,让测试人员只关注测试数据本身而从繁重的测试代码中解脱出来。每当我们进行测试时,只需要更新测试数据,自动化测试会根据这些数据判断应该执行什么测试,填入什么数据,得到什么预期。这个过程完全是以数据为主导的,所以我们称之为数据驱动。
2.代码实现
按照前面的设计,我们在项目下创建几个文件,如下图。总共有4个文件,分别对应上述的4个模块。
(1) TestData.xlsx:excel文件,用于存放接口测试的数据。
(2) Util.py:实现了一些通用工具的功能,比如读取excel。
(3) Common.py:封装了发送GET和POST请求的功能。
(4) Control.py:调度整个测试运行。

首先,我们在TestData.xlsx中设计好测试数据,由于上一节中设计excel中的接口测试数据时就考虑了接下来的任务,所以数据不用做出任何更改。测试数据的载体不一定非要使用excel,xml文件,数据库,甚至普通的txt文件都没有问题,当然使用excel是数据驱动最常见的方式。

然后我们实现执行模块Common.py,构造方法借助登录操作直接获取有效的cookie值并赋给成员属性self.cookies,成员方法httpGet和httpPost分别用于发送GET和POST请求,并返回响应对象。
import requests class Common: # 构造方法,实例化该类时则得到cookie def __init__(self): loginData = {'username':'boss','password':'boss123','verifycode':'1111'} loginRes = requests.post("http://localhost:8080/WoniuSales/user/login",data=loginData) self.cookies = loginRes.cookies # 发送GET请求 def httpGet(self, url): Res = requests.get(url) return Res # 发送POST请求 def httpPost(self, url, data): Res = requests.post(url, data=data, cookies=self.cookies) return Res |
接下来继续实现工具模块Util.py。
(1)readExcel函数,实现了读取excel并返回数据的功能,这里的index参数的默认值为0,代表默认读取excel中的第一个表。注意要提前安装并导入xlrd模块。
(2)解析参数的函数parseData,可以看到在excel的参数都是“参数名=参数值”的形式,为了传递给POST请求使用,需要把它利用字符串分割的方式,解析成键值对的形式,再存放到字典中并返回。
(3)assertResult函数,获取用例的信息进行断言,并输出可读性较高的结果。
import xlrd # 读取excel的函数,返回sheet对象 def readExcel(file_path, index = 0): # 打开指定路径的excel data = xlrd.open_workbook(file_path) # 获取整个sheet对象 sheet = data.sheets()[index] return sheet # 解析数据并重构 def parseData(str): strList = str.split('\n') newData = {} for line in strList: list = line.split('=') newData[list[0]] = list[1] return newData # 判断并输出执行结果 def asertResult(rowList, actCode, actContent): isPass = True # 连接用例编号与用例标题的字符串 print('############# 开始测试用例 ' + rowList[0] + ' - ' + rowList[1] + '###############') if rowList[5] == actCode and rowList[6] == actContent: print("测试用例通过!") else: isPass = False print('测试用例失败!') # 错误情况下,输出预期和实际的值,便于分析 print("状态码:" + "预期 - " + str(rowList[5]) + "实际 - " + str(actCode)) print("响应:" + "预期 - " + rowList[6] + "实际 - " + actContent) print('############# 结束测试用例 ' + rowList[0] + ' - ' + rowList[1] + '###############') return isPass |
最后是调度模块Control.py。
(1) 类中的构造方法__init__先初始化成员属性self.table,获取excel数据,self.countSucc统计成功用例数,self.countFail统计失败用例数,self.runTime统计执行时间。
(2) runTest方法整合测试,使用数据并断言,详细见注释。