应对公司项目需要,搭建一个简单实用的接口自动化测试框架,供测试人员实用,主要是用来做系统的业务流程功能验证,去除了大部分的异常校验。
这套框架使用的技术包括:pytest+requests+Excel+allure
下面先介绍一下该框架的分层结构:
config:用来存放读取Excel测试用例的方法
kword:用来存放用例执行过程中需要封装的方法
test_case:用来存放用例执行的测试代码
test_data:用来存放执行的测试用例,以excel方式
main_run:总执行文件
先新建excel文档auto_cases.xlsx,定义测试用例的模板,包括:编号、用例名称、URL、路径等信息,如下所示
创建测试用例后,将excel复制到test_data目录下
config目录下面新增excel_read.py,通过openpyxl包中的load_workbook方法自动读取excel文件中的数据,返回一个list_tulpe列表
'''
读取excel内容,实现文件驱动自动化执行
'''
import openpyxl
def read_Excel():
excel = openpyxl.load_workbook('./test_data/auto_cases.xlsx')
sheet = excel['Sheet1']
list_tulpe = []
# 逐行读取excel数据
for value in sheet.values:
# 判断当前第一列的值,是否是数值编号
if type(value[0]) is int:
# 将元祖装载进list
list_tulpe.append(value)
return list_tulpe
kword目录下新增api_key.py文件,新建接口关键字驱动类ApiKey,用于提供自动化接口测试的关键字方法
import json
import allure
import jsonpath
import requests
class ApiKey:
# 基于jsonpath获取数据的关键字,用于提取所需要的内容
def get_text(self,data,key):
# loads将json格式数据转换为字典格式
# dumps将字典格式的内容转换为json格式
dict_data = json.loads(data)
value_list = jsonpath.jsonpath(dict_data,key)
return value_list[0]
@allure.step("发送get请求")
# get请求的封装
def get(self,url, params=None, **kwargs):
return requests.get(url, params=params, **kwargs)
@allure.step("发送post请求")
# post请求的封装
def post(self,**kwargs):
return requests.post(**kwargs)
test_case目录下面新增test_excel.py,实现测试用例执行
import openpyxl
import pytest
import allure
from config.excel_read import read_Excel
from kword.api_key import ApiKey
def setup_module():
# 1.定义全局变量
global excel, sheet, excel_path, ak, all_val,result
# 2.初始化Excel文件
excel_path = './test_data/auto_cases.xlsx'
excel = openpyxl.load_workbook(excel_path)
sheet = excel['Sheet1']
# 3.实例化工具类
ak = ApiKey()
# 4.初始化字典
all_val = {}
result = None
@pytest.mark.parametrize('organ',read_Excel())
def test_organ(organ):
r = organ[0] + 1
# 如果存在自定义标题
if organ[1] is not None:
# 动态生成标题
allure.dynamic.title(organ[1])
# 动态获取级别信息
if organ[16] is not None:
allure.dynamic.severity(organ[16])
# 动态获取模块名称
if organ[14] is not None:
allure.dynamic.feature(organ[14])
# 动态获取用例功能名称
if organ[15] is not None:
allure.dynamic.story(organ[15])
# 判断当前行的第一列的值,是否是数字编号
if type(organ[0]) is int:
# 准备需要的测试数据
# 请求参数
data = organ[6]
# 校验字段
assert_value = organ[8]
# 预期结果字段
expect_value = organ[9]
if organ[6]:
dict_data = {
# 不能直接取字符串,要求是字典
'url': organ[2] + organ[3],
# eval官方解释:将字符串str当做有效的表达式来求值并返回计算结果
# 这里直接给headers一个字典值
'headers': eval(organ[5]),
organ[7]: eval(data)
}
else:
dict_data = {
'url': organ[2] + organ[3],
'headers': eval(organ[5])
}
print(dict_data)
# 使用反射模拟请求
res = getattr(ak, organ[4])(**dict_data)
if organ[12] is not None:
if ';' in organ[12]:
# ===============JSON提取,多参数版================
varStr = organ[12]
# 用分号分割varStr字符串,并保存到列表里
varStrList = varStr.split(';')
# 获取varStrList列表长度
length = len(varStrList)
# 遍历分割JSON表达式
jsonStr = organ[13]
jsonList = jsonStr.split(';')
# 循环输出列表值
for i in range(length):
# json引用变量名获取
key = varStrList[i]
# json表达式获取
jsonExp = jsonList[i]
# 字典值的获取
valueJson = ak.get_text(res.text, jsonExp)
# 变量和值的存储
all_val[key] = valueJson
else:
# ===============JSON提取,单参数版================
# 根据Excel填写的json表达式动态获取值
valueJson = ak.get_text(res.text, organ[13])
# 将获取到的token值赋值给Excel中定义的变量名,用定义的字典all_val保存相应得到的键值
# 变量名获取
key = organ[12]
all_val[key] = valueJson
print('key值为:' + key)
print(valueJson)
# 结果校验
# 实际结果
# 给它一个默认值,让异常的报错信息好检查一些
result = ak.get_text(res.text, assert_value)
print('==========检查信息=========')
print("检验字段:" + organ[8])
print("预期结果:" + str(organ[9]))
print("实际结果:" + str(result))
sheet.cell(r, 11).value = result
if result == expect_value:
sheet.cell(r, 12).value = '通过'
else:
sheet.cell(r, 12).value = '不通过'
excel.save(excel_path)
assert result == organ[9]
根目录下创建一个main_run.py执行函数
import os
import pytest
from config.excel_read import read_Excel
if __name__ == '__main__':
pytest.main(['./test_case/test_excel.py', '--alluredir', './result', '--clean-alluredir'])
os.system('allure serve result')