1、首先新建一个excel文档
sheet1中的数据如下:
sheet2中的数据如下:
2、脚本如下,只校验了get和post的单接口测试
'''
接口测试脚本,
读取写好的excel测试用例,然后根据excel中的内容进行调用,
判断预期结果是否和返回报文中的值一致,并生成新的excel报告。
此脚本要求对python中操作excel的模块xlrd熟悉
注意: excel的行和列在python中都是从0开始
xlrd模块0.8版本后不支持以xlsx为后缀名文件,所以使用这个方法的时候,excel要用xls格式的,不然可能会导致保存的文件无法打开
'''
import requests, xlrd, time
from xlutils.copy import copy # 复制表格必须用此copy
# 读取excel测试用例
def read_excel(file_path):
'''
file_path:传入的excel文件的绝对路径
return:返回这个excel第一个sheet页中的所有测试用例的list
'''
try:
book = xlrd.open_workbook(file_path) # 打开excel
except Exception as e:
print('路径不在或者excel不正确/n', e) # 如果路径不在或者excel不正确,返回报错信息
else:
sheet = book.sheet_by_index(1) # 取第一个sheet页,即文档的第一个工作表
rows = sheet.nrows # 取这个sheet页(当前表)的所有行数
case_list = [] # 定义一个空列表,用来保存每一条case
for i in range(rows): # 循环表中的每一行
if i != 0: # 去除表头,因为是从0开始,所以表头的索引是0
# 用例以行的维度添加到case_list中,每一行又是一个单独的小列表,以单元格拆分成小列表中的每一项
case_list.append(sheet.row_values(i))
# 调用接口测试的函数,把存所有case的list和excel的路径传进去
interface_test(case_list) # 请求接口
# 请求接口并测试
def interface_test(case_list):
test_msgs = [] # 存测试结果的list
request_msgs = [] # 存请求报文的list
responses = [] # 存返回报文的list
for case in case_list:
'''
先遍历excel中每一条case的值,然后根据对应的索引取到case中每个字段的值
'''
try: # 这里捕捉一下异常,如果excel格式不正确的话,就返回异常
method = case[4] # 请求方式
url = case[5] # 请求url
param = case[6] # 入参
res_check = case[7] # 预期结果
except Exception as e:
return ('测试用例格式不正确!%s' % e)
if param == '':
'''
如果请求参数是空的话,请求报文就只有url,然后把请求报文存到请求报文list中
'''
new_url = url # 请求报文
request_msgs.append(new_url)
else:
'''
如果请求参数不为空的话,请求报文就是url+?+参数,格式如下:
https://testm.yoho8.com/apiuser/shop/integral?type=2,然后把请求报文存到请求报文list中
'''
'''
excel里面的如果有多个入参的话,参数是用;隔开,如:"a=1;b=2"这样的,请求的时候多个参数要用&连接。格式如下:
https://testm.yoho8.com/apiuser/shop/integral?type=2&id=1
要把;替换成&,所以调用了urlParam这个函数,把参数中的;替换成&,这个函数在下面手动定义的
'''
new_url = url + '?' + urlParam(param) # 请求报文,等同于请求中的Request URL
request_msgs.append(new_url)
if method.upper() == 'GET':
'''
如果是get请求就调用requests模块的get方法,.text是获取返回报文,并保存在返回报文的list中
'''
results = requests.get(new_url, headers=headers).text # 获取返回报文
responses.append(results) # 保存返回的报文
'''
获取到返回报文之后需要根据【预期结果】去判断测试是否通过,
调用查看结果方法read_res,把返回报文和预期结果传进去,判断是否通过,read_res方法在下面定义了。
'''
res = read_res(results, res_check) # 把返回报文赋值,然后判断是否通过
else:
'''
如果是post请求,就调用requests模块的post方法,.text是获取返回报文,并保存在返回报文的list中
'''
results = requests.post(new_url, headers=headers).text
responses.append(results)
'''
获取到返回报文之后需要根据【预期结果】去判断测试是否通过
调用查看结果方法read_res,把返回报文和预期结果传进去,判断是否通过,readRes方法在下面定义了。
'''
res = read_res(results, res_check) # 把返回报文赋值,然后判断是否通过
if 'pass' in res: # 也可以用if res == 'pass',但是不确定res中是否有其他字符,用in相对保险
'''
判断测试结果,pass就是通过,fail就是失败
'''
test_msgs.append('pass')
else:
test_msgs.append('fail')
'''
全部用例执行完之后,会调用copy_excel方法,把测试结果写到excel中,
每一条用例的请求报文、返回报文、测试结果在上面都定义了一个list,来存每一条用例执行的结果,
把源excel用例的路径和三个list传进去调用即可,copy_excel方法在下面定义了
'''
copy_excel(file_path, test_msgs, request_msgs, responses) # 把测试结果写到excel中
# 判断返回报文和预期结果是否一致
def read_res(res, res_check):
'''
res: 返回报文
res_check: 预期结果
:return: 通过或者不通过,不通过的话会把和预期不一致的参数返回
'''
'''
接口返回报文是这样的格式 {"id":"J_775682","p":275.00,"m":"458.00"}
excel预期结果中的格式是 xx=11;xx=22 这样的,所以要把返回报文改成xx=22这样的格式
所以用到字符串替换,把返回报文中的":"和":替换成=,返回报文就变成
{"id=J_775682","p=275.00,"m=458.00"},这样就和预期结果一样了
可以用python自带的json模块来解析json串,但是有的返回的不是标准的json格式,处理起来比较麻烦,这里我就用字符串的方法了
'''
res = res.replace('":"', '=').replace('":', '=')
'''
res_check是excel中的预期结果,是xx=11;xx=22这样的
所以用split分割字符串,变成一个list['xx=1','xx=2']这样的,
然后遍历预期结果,判断预期结果中的每个元素是否存在返回报文中,
如果每个元素都在返回报文中的话,就说明和预期结果一致
'''
res_check = res_check.split(';')
for s in res_check:
'''
遍历预期结果,如果当前字符串在返回报文中,什么都不做(pass就可以)
如果不存在的话,就返回错误信息和不一致的字段
全部都存在的话,就return pass,证明结果一致
因为res_check是从excel里面读出来的,字符是Unicode类型的,python的字符串是str类型的,
所以要用str方法将res_check中的字符串强制转换成str类型的
'''
if s in res:
pass
else:
return '错误,返回参数和预期结果不一致' + str(s)
return 'pass'
# 参数中的符号转换
def urlParam(param):
'''
excel中的多个参数是使用;分割,请求时要转换成xx=11&xx=2这样,把参数中的;替换成&
'''
return param.replace(';', '&')
# 把测试结果写到excel中
def copy_excel(file_path, test_msgs, request_msgs, responses):
'''
file_path: 测试用例的路径
test_msgs: 测试结果的list
request_msgs: 请求报文的list
responses: 返回报文的list
'''
'''
把请求报文、返回报文、测试结果写到测试用例的excel中
因为xlrd模块只能读excel,不能写,python中没有一个模块能直接操作已经写好的excel
所以只能用xlutils模块中的copy方法,copy一个新的excel,才能操作写
'''
book = xlrd.open_workbook(file_path) # 打开原来的excel,获取到这个book对象
new_book = copy(book) # 复制一个new_book
new_sheet = new_book.get_sheet(1) # 然后获取到这个复制的excel的第一个sheet页,即第一张表
i = 1
for request_msg, response, test_msg in zip(request_msgs, responses, test_msgs):
'''
同时遍历请求报文、返回报文和测试结果这3个大的list
然后把每一条case的执行结果写到excel中,zip函数可以将多个list放在一起遍历
因为第一行是表头,所以从第二行开始写,也就是索引位1的位置
i代表行,所以i赋值为1,然后每写一条,就i+=1
请求报文、返回报文、测试结果分别在excel的8、9、11列,列是固定的,所以就写死了
后面跟上要写的值,因为excel用的是Unicode字符编码,所以前面带个u表示用Unicode编码,否则会有乱码
'''
new_sheet.write(i, 8, u'%s' % request_msg) # 如果i=1就表示第一行第8列写入request_msg
new_sheet.write(i, 9, u'%s' % response)
new_sheet.write(i, 11, u'%s' % test_msg)
i += 1
# 全部结果写完之后在指定目录保存一个以当前时间命名的测试结果文件,time.strftime()是格式化日期
new_book.save('/Users/chensihan/Desktop/%s_测试结果.xls' % time.strftime('%Y%m%d%H%M%S'))
if __name__ == '__main__':
'''
调用的时候需要传入一个excel,调用方式是 python xx.py xx.xls
sys.argv[1]的意思是取传入的第二个参数,也就是索引是1的,
第一个是这个python文件的文件名,如果不传入参数运行的话,会提示错误,如果正确的话,
会调用读excel的程序,执行用例,运行完成后,会打印执行完毕
'''
file_path = '/Users/chensihan/Desktop/test.xlsx' # excel的绝对路径
headers = {'content-type': 'application/json', # 调用接口时需要传入的headers
'channelcode': 'SH002',
'devicetype': 'miniProgram',
'token': '914abd88d5e84838aa977b2b77c5fad6'}
read_excel(file_path)
print('执行完毕!!!')
'''
1、 写好excel的用例模板,需要有的字段: 项目、用例id、接口名称、用例描述、请求方式、url请求地址、请求参数(多个的参数话用;分号隔开)、
结果验证(多个的参数话用;分号隔开)、请求报文、返回报文、测试人员、测试结果
2、读取Excel中的内容
3、根据excel中的 请求url和参数 拼接请求报文,调用接口,并保存返回报文
4、读取返回报文,和预期结果对比,不一致把请求报文、返回报文和测试结果写到复制的测试用例的excel中。
'''
get 和 post接口测试
结束。