forked from DxvLwRYF/apiAutoTest
153 lines
4.4 KiB
Python
153 lines
4.4 KiB
Python
|
#!/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 json
|
|||
|
|
|||
|
import mitmproxy.http
|
|||
|
import xlwt
|
|||
|
|
|||
|
# 上传文件接口不能录入文件参数 , excel单元格限制: Exception: String longer than 32767 characters
|
|||
|
from mitmproxy import ctx
|
|||
|
|
|||
|
|
|||
|
class 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 -stools\recording 启动
|
|||
|
ctrl + C 停止 并生成完整用例
|
|||
|
"""
|