概述:
(what)接口自动化是指模拟接口层面的自动化。(why)因为成本低可维护性高逐渐成为自动化测试的主流方向之一。
一、简要说明
环境:Python3.6,Unittest,Requests,Mock,DDT
ParamUnittest = 0.2
configparser = 5.0.0
ddt = 1.4.1
jsonpath = 0.82
mock = 4.0.2
openpyxl = 3.0.4
requests = 2.24.0
HTMLTestRunner= 0.9.1
流程说明:读取EXCEL测试数据->生成测试用例->执行测试用例->结果写入EXCEL->生成HTMLTestRunner报告
模块、类、包的设计说明:
baserequest.py 封装requests方法,支持(post\get\put)多协议扩展
handle_ini.py 读取配置文件,包括:域名的配置,email的配置,数据库的配置,取值规则的配置
mockvalue.py 封装mock响应值的方法,如依赖数据
Util/handl*.py token处理,json处理,封装用来assert的断言数据处理
RunCase.py 核心代码。聚合用例集并执行,最后生成报告
Excel测试数据格式如下图所示:
二、框架结构与流程
1.框架结构如下图所示:
2.框架流程图如下图所示:
三、代码功能分析
1、Config.ini配置文件
此文件中[server]为域名相关配置,[json]为json处理规则相关配置
[server]
host=测试
username=测试
password=测试
[database]
database=测试
username=测试
password=测试
[json]
token_rule = $..token
2、openpyxl读取excel数据
一个接口可以定义多条case,get_excel_data为封装了读取所有excel中case的方法,最终存储到一个嵌套list中。
class HandExcel():
def get_excel_data(self):
"""exccel里面所有的case数据以列表嵌套list存储)"""
data_list = []
for i in range(self.get_rows()):
data_list.append(self.get_rows_value(i + 2))
return data_list[:-1]
3、ddt数据驱动获取所有case
在执行函数内获取所有的case,原理和for循环相似
@ddt.ddt
class Test_Index(unittest.TestCase)
@ddt.data(*data)
def test_mainindex(self, data):
"""执行case主流程"""
case_id = data[0]
i = excel_data.get_rows_number(case_id) # 行号
is_run = data[2]
if is_run == "yes":
data1 = json.loads(data[7])
is_depend = data[3]
4、编写测试用例
@ddt.ddt
class Test_Index(unittest.TestCase):
@ddt.data(*data)
def test_mainindex(self, data):
# 用例描述:调用商品分类接口拿到并根据依赖数据查询商品详情列表
header = None
get_token = None
is_run = data[2]
if is_run == "yes":
url = data[5]
method = data[6]
expected_method = data[10]
res = BaseRequest.run(method, url, data1, get_token, header)
code = res['meta']["status"]
message = res['meta']["msg"]
if expected_method == "mec":
configmes = handle_result_msg(url, code)
self.assertEqual(configmes, message)
5、运行框架的主程序
class RunCase():
def runcase(self): # unittest discover管理case
case_path = os.path.join(base_path, "testCase")
discover = unittest.defaultTestLoader.discover(case_path, pattern="test*.py")
result_path = os.path.join(base_path, "Report", "report.html")
with open(result_path, "wb") as f:
runner = HTTPTestRunner.HTMLTestRunner(stream=f, title="测试报告", description="测试人员:ysz")
runner.run(discover)
6、logs INFO示例
2020-08-13 18:13:06,111 - logs… - INFO - D:\untitled\untitled\shopvinterface\Report\report.html
2020-08-13 18:13:06,112 - logs… - INFO - D:\untitled\untitled\shopvinterface\Run\testcase1_ddt.py
7、Mock部分代码
def mock_depend():
"""mock依赖数据"""
data = {
"data": {
"id": 1
}
}
depend_value = data.get('data').get('id')
get_data = mock.Mock(return_value=depend_value)
res = get_data
return res()
8、baserequest部分代码
class BaseRE():
"""基础请求"""
def send_post(self, url, data, get_token=None, header=None):
"""post请求"""
request = requests.Session() # 自动关联session
res = request.post(url=url, data=data, headers=header).json()
if get_token is not None:
"""token写入"""
token = ' '.join(jsonpath.jsonpath(res, '$..token'))
header2 = {"Authorization": token}
write_token(header2, get_token["is_token"])
return res
四、HTMLTestRunner报告总览及Excel结果
1.HTMLTestRunner报告总览如下图所示:
2.Excel结果如下图所示:
五、jenkins集成
使用jenkins插件生成HTMLTestRunner报告
六、框架扩展优化
进行中...
七、shell脚本自动执行框架
使用了shell脚本自动执行框架,每次执行前清空日志,并输出最新日志到控制台:
项目Github地址:https://github.com/Keith-Yong/pyapiservice
客官请留步!
点个赞❤️再走~~