为什么要做接口自动化框架
1、业务与配置的分离
2、数据与程序的分离;数据的变更不影响程序
3、有日志功能,实现无人值守
4、自动发送测试报告
5、不懂编程的测试人员也可以进行测试
正常接口测试的流程是什么?
确定接口测试使用的工具----->配置需要的接口参数----->进行测试----->检查测试结果----->生成测试报告
测试的工具:python+requests
接口测试用例:excel
一、接口框架如下:
1、action包:用来存放关键字函数
2、config包:用来存放配置文件
3、TestData:用来存放测试数据,excel表
4、Log包:用来存放日志文件
5、utils包:用来存放公共的类
6、运行主程序interface_auto_test.py
7、Readme.txt:告诉团队组员使用改框架需要注意的地方
二、接口的数据规范设计—Case设计
一个sheet对应数据库里面一张表
APIsheet存放
编号;从1开始
接口的名称(APIName);
请求的url(RequestUrl);
请求的方法(RequestMethod);
传参的方式(paramsType):post/get请求方法不一样
用例说明(APITestCase)
是否执行(Active)部分接口已测通,下次不用测试,直接把这里设置成N,跳过此接口
post与get的区别
查看post详情
post请求参数一般是json串,参数放在from表单里面;参数一般不可见,相对来说安全性高些
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8FnQFePQ-1591101885951)(https://upload-images.jianshu.io/upload_images/23053034-816cdf7d3e2a1dbd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
查看get详情
get请求参数一般直接放在url里面
2.1注册接口用例
RequestData:请求的数据
(开发制定的传参方式)
RelyData:数据依赖
ResponseCode:响应code
ResponseData:响应数据
DataStore:存储的依赖数据;如果存在数据库里面,在表里增加一个字段用来存依赖的数据
(存储的方式是编写接口自动化的人员来设定的存储方式)
CheckPoint:检查点
Active:是否执行
Status:执行用例的状态,方便查看用例是否执行成功
ErrorInfo:case运行失败,失败的错误信息;eg:是也本身的原因还是case设置失败,还是其他原因
2.2登录接口用例
RequestData:请求的数据
(开发制定的传参方式)
RelyData:数据依赖
(存储的方式是编写接口自动化的人员来设定的存储方式)
ResponseCode:响应code
ResponseData:响应数据
DataStore:存储的依赖数据;如果存在数据库里面,在表里增加一个字段用来存依赖的数据
(存储的方式是编写接口自动化的人员来设定的存储方式)
CheckPoint:检查点
Active:是否执行
Status:执行用例的状态,方便查看用例是否执行成功
ErrorInfo:case运行失败,失败的错误信息;eg:是也本身的原因还是case设置失败,还是其他原因
重点说明下RelyData:数据依赖
采取的是字典:key:value来存储数据格式;
{“request”:{“username”:“register->1”,“password”:“register->1”},“response”:{“code”:“register->1”}}
格式化之后:
{
"request":{
"username":"register->1",
"password":"register->1"
},
"response":{
"code":"register->1"
}
}
三、创建utils包:用来存放公共的类
3.1 ParseExcel.py 操作封装excel的类(ParseExcel.py)
#encoding=utf-8
import openpyxl
from openpyxl.styles import Border, Side, Font
import time
class ParseExcel(object):
def __init__(self):
self.workbook = None
self.excelFile = None
self.font = Font(color = None) # 设置字体的颜色
# 颜色对应的RGB值
self.RGBDict = {'red': 'FFFF3030', 'green': 'FF008B00'}
def loadWorkBook(self, excelPathAndName):
# 将excel文件加载到内存,并获取其workbook对象
try:
self.workbook = openpyxl.load_workbook(excelPathAndName)
except Exception as err:
raise err
self.excelFile = excelPathAndName
return self.workbook
def getSheetByName(self, sheetName):
# 根据sheet名获取该sheet对象
try:
# sheet = self.workbook.get_sheet_by_name(sheetName)
sheet = self.workbook[sheetName]
return sheet
except Exception as err:
raise err
def getSheetByIndex(self, sheetIndex):
# 根据sheet的索引号获取该sheet对象
try:
# sheetname = self.workbook.get_sheet_names()[sheetIndex]
sheetname = self.workbook.sheetnames[sheetIndex]
except Exception as err:
raise err
# sheet = self.workbook.get_sheet_by_name(sheetname)
sheet = self.workbook[sheetname]
return sheet
def getRowsNumber(self, sheet):
# 获取sheet中有数据区域的结束行号
return sheet.max_row
def getColsNumber(self, sheet):
# 获取sheet中有数据区域的结束列号
return sheet.max_column
def getStartRowNumber(self, sheet):
# 获取sheet中有数据区域的开始的行号
return sheet.min_row
def getStartColNumber(self, sheet):
# 获取sheet中有数据区域的开始的列号
return sheet.min_column
def getRow(self, sheet, rowNo):
# 获取sheet中某一行,返回的是这一行所有的数据内容组成的tuple,
# 下标从1开始,sheet.rows[1]表示第一行
try:
rows = []
for row in sheet.iter_rows():
rows.append(row)
return rows[rowNo - 1]
except Exception as err:
raise err
def getColumn(self, sheet, colNo):
# 获取sheet中某一列,返回的是这一列所有的数据内容组成tuple,
# 下标从1开始,sheet.columns[1]表示第一列
try:
cols = []
for col in sheet.iter_cols():
cols.append(col)
return cols[colNo - 1]