当我们在接口或UI自动化项目中,常常会出现这种现象——明明是正常请求,却无法获取到想要的数据返回。
比如:
场景A:页面是动态数据,第一次进入页面获取到的数据,和下次进入页面获取到的数据完全不一样。
场景B:页面数据有展示限制,页面某些模块或整个页面数据仅展示3次,且通过服务端返回控制。
这时我们要怎么办?
如果是手工测试时,我们大可以直接使用Charles、Fiddler进行模拟,毕竟代理软件基本能解决大部分测试需求。
那如果是在自动化项目中呢?如果还是使用代理软件——其实也不是完全不行,但我们还有更佳的实践方式。
也就是使用MitmProxy作为正向代理拦截请求和返回数据。
MitmProxy是一个三方库,我们在程序中可以把它当成Charles来使用。
这里以实现Maplocal功能进行说明。
(1)Maplocal功能,简单理解就是当针对特定请求,返回特定数据。
{ "post": { "title": "百度一下", }, "type": 1 }
但我们修改返回数据,只要有"www.baidu.com"请求过来,就让它自动返回:
{ "post": { "title": "谷歌一下啦啦啦", }, "type": 1 }
这就是一个最基础的maplocal案例。
(2)在MitmProxy里如何实现Maplocal功能呢?
这里以get请求实现进行说明:
- get.json 配置文件,在这里记录所有需要拦截的get请求
{ "https:www.baidu.com":[ { "jsonPath":"../data/maplocal/first_tab.json" } ] }
- mitmproxy脚本中
from mitmproxy import http from mitmproxy import ctx class InterceptRequests: def __init__(self): def request(self, flow: http.HTTPFlow) -> None: """ 使用request事件实现map local :param flow: :return: """ # GET 请求处理 if method == "GET": pure_url = get_url_host(interceptUrl) url_data = get_json.get(pure_url) if url_data: interce_params = get_url_params(interceptUrl) params = get_json_value(get_path, pure_url) for para in params: if para.items() <= interce_params.items(): jsonpath = para.get("jsonPath") jsonpath_abs = path(jsonpath) self.file_maplocal(flow, jsonpath_abs) addons = [ InterceptRequests() ]
- 在执行的脚本中(如本地shell 或 其他执行的py脚本里)
# kill mitmproxy lsof -n -i:8999 | grep LISTEN | awk '{print $2}' | xargs kill # start mitmproxy mitmdump -p 8999 -s mitmHandler.py
启动脚本后,连接mitmproxy的设备的请求全部都会被脚本监控。
如果出现"www.baidu.com"的请求,就会到get.json里找到对应的json,自动返回给设备。
这样,就实现了一个最简单的maplocal。
当然基于目前的mitmproxy脚本,我们还可以进行一些功能扩展。
如针对接口类型-get 或 post请求,针对请求参数类型-json 或 x-www-form-urlencoded,都可以进行更多延伸扩展。