
本文共 5446 字,大约阅读时间需要 18 分钟。
apiAutoTest
先软文介绍下:apiAutoTest是个人和众多测试同行参与(提供新的需求)的一个接口测试工具项目.
Gitee:
Github:
目前功能
- [x] 测试前后数据库备份操作,个人理解算数据清洗
- [x] 各接口之间的测试数据依赖
- [x] 自定义扩展函数定义,解决部分加密算法
- [x] 后置sql,结果用于依赖或者断言(select 语句只能查出第一条)1. * *
- [x] 实际结果可动态提取,与预期结果绝对
==
- [x] 可选用例失败重跑机制
- [x] 基于mitmproxy录制接口生成用例文件
重大更新(个人认为)
在之前的一篇自定义函数简单实现方式时,有提醒到语法可能出现冲突,所以在前两天更新时已经统一了语法${}
无论是使用依赖参数还是自定义方法都使用${}
, 为了避免每次使用其他接口返回提取jsonpath
表达式在用例中的冗余(或许也提高了些性能,之前版本是会保存整个响应内容的),用例中增加了提取参数
来实现形式如下
{ // key -> id 为其他接口使用时的参数变量 用法 ${id} "id": "$.data.id" // $.data.id 实则为jsonpath表达式 从当前响应中提取id值}
相关使用文档: 可到源码Readme.md 文件中前往 在线文档查看
本次更新
**本次更新内容使用演示视频: **
契机
有同志,希望有个录制功能来减少手写参数的时间
根本
基于mitmproxy, 使用其提供的扩展API, 通过mitmproxy 实现代理之后捕获到HTTP/HTTPS请求,并把请求已追加的形式添加到excel中,当录制完成务必使用ctrl + c 关闭录制,将生成一个完成的用例数据文件
可指定录制包含请求地址的接口
如何录制
前置条件:
打开本机代理
修改
tools\recording.py
中配置抓包请求地址, 用例生成路径apiAutoTest
根目录下执行mitmweb -s tools\recording.py
正常去使用就行了,当不需要录制的时候 在上面这个窗口
Ctrl + C
停止录制,然后关闭本机代理
录制的用例
因为默认录制的url是完整的url,所以如果直接用这个文件,请把config/config.yaml
中的serve
dev 基准地址换成""
, 因为条件有限没法覆盖测试很多内容这快功能可能会有Bug
, 目前个人测试了Graphql
规范接口的录制,RestFul
规范接口录制, 不排除其他的无法完整的生成用例文件
需要注意Excel 单元格字符数限制问题, Graphql规范接口非常容易出现不可写入的情况, 单从业务接口来说应该不容易出现此类问题
执行录制的用例
config/config.yaml
修改基准地址dev
为""
,指定使用录制的用例文件
server: # 本地接口服务 test: http://127.0.0.1:8888/ # https://space.bilibili.com/283273603 演示项目后端服务来自# dev: http://www.ysqorz.top:8888/api/private/v1/ dev: ''# 基准的请求头信息request_headers: {}file_path: test_case: data/case_data1.xls # 指定使用那个用例,这里使用了录制的用例 report: report/ log: log/run{time}.log....
执行结果
实现源码
#!/usr/bin/env/ python3# -*- coding:utf-8 -*-"""@Project: apiAutoTest@File :recording.py@Author:zy7y@Date :2021/5/21 22:07@Desc : 录制接口,生成用例文件基于mitmproxy实现参考资料:https://blog.wolfogre.com/posts/usage-of-mitmproxy/https://www.cnblogs.com/liuwanqiu/p/10697373.html"""import jsonimport mitmproxy.httpimport xlwt# 上传文件接口不能录入文件参数 , excel单元格限制: Exception: String longer than 32767 charactersfrom mitmproxy import ctxclass Counter: def __init__(self, filter_url: str, filename: str = "data/case_data1.xls"): """ 基于mitmproxy抓包生成用例数据 :param filter_url: 需要过滤的url :param filename: 生成用例文件路径 """ self.url = filter_url self.excel_row = [ '编号', '用例标题', '请求头', '接口地址', '是否执行', '请求方式', '入参关键字', '上传文件', '请求数据', '提取参数', '后置sql', '预期结果'] self.cases = [self.excel_row] self.counter = 1 self.file = filename def response(self, flow: mitmproxy.http.HTTPFlow): """ mitmproxy抓包处理响应,在这里汇总需要数据 :param flow: :return: """ if self.url in flow.request.url: # 编号 number = "C" + str(self.counter) # 标题 title = "mitmproxy录制接口" + str(self.counter) try: token = flow.request.headers["Authorization"] except KeyError: token = '' header = json.dumps({"Authorization": token}) data = flow.request.text # 请求地址,config.yaml 里面基准环境地址 写 空字符串 method = flow.request.method.lower() url = flow.request.url try: content_type = flow.request.headers['Content-Type'] except KeyError: content_type = '' if 'form' in content_type: data_type = "data" elif 'json' in content_type: data_type = 'json' else: data_type = 'params' if '?' in url: data = url.split('?')[1] data = self.handle_form(data) # 预期结果 expect = json.dumps( {".": json.loads(flow.response.text)}, ensure_ascii=False) # 日志 ctx.log.info(url) ctx.log.info(header) ctx.log.info(content_type) ctx.log.info(method) ctx.log.info(data) ctx.log.info(flow.response.text) case = [ number, title, header, url.split('?')[0], "是", method, data_type, "", data, "", "", expect] self.cases.append(case) self.counter += 1 # 文件末尾追加 self.excel_cases() def excel_cases(self): """ 对二维列表cases进行循环并将内容写入单元格中 :return: """ workbook = xlwt.Workbook() worksheet = workbook.add_sheet('用例数据') for x in range(len(self.cases)): for y in range(len(self.cases[x])): worksheet.write(x, y, self.cases[x][y]) try: workbook.save(self.file) except Exception as e: print(e) def handle_form(self, data: str): """ 处理 Content-Type: application/x-www-form-urlencoded 默认生成的数据 username=admin&password=123456 :param data: 获取的data 类似这样 username=admin&password=123456 :return: """ data_dict = {} if data.startswith('{') and data.endswith('}'): return data try: for i in data.split('&'): data_dict[i.split('=')[0]] = i.split('=')[1] return json.dumps(data_dict) except IndexError: return ''addons = [ Counter("http://www.ysqorz.top:8888/api/private/v1/")]"""mitmweb -s tools\recording.py 启动ctrl + C 停止 并生成完整用例"""
参考资料
发表评论
最新留言
关于作者
