前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >移动端异常数据测试

移动端异常数据测试

作者头像
测试加
发布2022-03-24 15:51:55
1K0
发布2022-03-24 15:51:55
举报
文章被收录于专栏:用户4624600的专栏

背景

在测试阶段或者在一些特殊环境,经常因为某些数据导致客户端崩溃.

比如后端接口数据返回某个字段为空、某个字段类型变了、数组为空等.此时如果客户端没有兼容这些异常行为,大多数情况会导致崩溃.

所以为了保证客户端在任何异常数据的情况下都能兼容(不崩溃),需要进行异常数据测试.

异常数据测试方法

在以前手工测试阶段,我们一般借助fidder或者charles工具.对返回结果拦截修改数据,再进行数据的maplocal.

比如对一个字段的返回值改为空,如下图:

异常数据修改规则

字符

  • 非法字符
  • 超长
  • null

数组

  • 空数组
  • 非法序列

接口超时

如3s、5s、10s

接口状态码

如404、500、503

增加数据

  • 数组
  • 字典

删除数据

  • 数组
  • 字典

自定义代理

制造异常数据的关键是对数据拦截并修改,上述讲到的使用charles工具.但是charles工具不太灵活、不能开发扩展脚本.

调研了一些目前比较好用的代理工具:

  • anyProxy<br> 开源使用Node.js开发的轻量级代理工具 https://github.com/alibaba/anyproxy/blob/master/docs/cn/src_doc.md
  • mitmproxy<br> mitmproxy使用比较小众,特点在于可使用python语言二次开发脚本,安装也比较简单.<br> https://mitmproxy.org

mitmproxy

本文主要选用mitmproxy二次开发,主要是因为结合python语言和python类库,比较容易上手.

mitmproxy安装

在mac环境下安装命令:

代码语言:javascript
复制
brew install mitmproxy

mitmweb

mitmweb是提供的web可视化工具,界面提供查看和筛选接口数据.

启动命令:

代码语言:javascript
复制
mitmweb

mitmdump

mitmdump无交互界面的命令,可与python脚本对接.

启动命令:

代码语言:javascript
复制
mitmdump

脚本实例

代码语言:javascript
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
拦截请求的request
"""

from mitmproxy import http

def request(flow: http.HTTPFlow):
    # redirect to different host
    if flow.request.pretty_host == "example.com":
        flow.request.host = "mitmproxy.org"
    # answer from proxy
    elif flow.request.path.endswith("/brew"):
    	flow.response = http.HTTPResponse.make(
            418, b"I'm a teapot",
        )

常用的API

实例request

代码语言:javascript
复制
flow.request.headers #获取所有头信息,包含Host、User-Agent、Content-type等字段
flow.request.url #完整的请求地址,包含域名及请求参数,但是不包含放在body里面的请求参数
flow.request.pretty_url #同flow.request.url目前没看出什么差别
flow.request.host #域名
flow.request.method #请求方式。POST、GET等
flow.request.scheme #什么请求 ,如https
flow.request.path # 请求的路径,url除域名之外的内容
flow.request.get_text() #请求中body内容,有一些http会把请求参数放在body里面,那么可通过此方法获取,返回字典类型
flow.request.query #返回MultiDictView类型的数据,url直接带的键值参数
flow.request.get_content()#bytes,结果如flow.request.get_text()
flow.request.raw_content #bytes,结果如flow.request.get_content()
flow.request.urlencoded_form #MultiDictView,content-type:application/x-www-form-urlencoded时的请求参数,不包含url直接带的键值参数
flow.request.multipart_form #MultiDictView,content-type:multipart/form-data
时的请求参数,不包含url直接带的键值参数

实例response

代码语言:javascript
复制
flow.response.status_code #状态码
flow.response.text#返回内容,已解码
flow.response.content #返回内容,二进制
flow.response.setText()#修改返回内容,不需要转码

设计流程

在上面提到可以拦截request和response,那么就可以对response数据做修改,再返回修改后的数据.

基于上面提到修改数据规则,随机多拦截数据做随机修改.

保存修改前和修改后的数据,方便数据diff.

设计流程图如下:

定义数据类型

例如png、html、img这些静态资源不需要修改,直接返回即可.

定义随机事件

目前做到的规则是,随机对接口做修改,基于定义好的随机事件.

  • 修改json
  • 修改字符串
  • 修改列表
  • 修改返回事件
  • 修复状态码

修改字符串

修改字符串是修改数据中最常用的方式,比如对返回json中的某一个字段或者多个名字一样的字段做修改value值.

遍历json

因为返回的json一般都是深层嵌套json数据,所以需要把json中的每一字段都组装成tree,形成一条链路.

在json中有东西叫jsonpath,通过jsonpath就可以找到对应的value值.

那么我们就可以遍历json,生成N条jsonpath路径.

重新生成json

有个上面我们提到jsonpath,我们就可以随机对一条或者多条jsonpath修改数据,然后重新set回去.

但是和遗憾的是python并没有现成的根据jsonpath修改json的库, 在网上参考了一些帖子并重新修改了一些代码,代码片段如下:

在修改数据之后调用flow.response.set_text把修改后的数据set回去.

数据diff

把每次数据修改前和修改后保存到本地log文件.

报告中记录每次的接口数据信息.

报告详情中展示接口详情.

效果

最终的执行命令:

代码语言:javascript
复制
mitmdump -s proxyserver.py(二次开发脚本名字)

手机代理设置端口(127.0.0.1:80)

在使用这个脚本是结合了monkey脚本,也发现了一些因为数据异常的崩溃.

UI上展示修改数据

类型错误导致崩溃

结语

在着手开发工具的初衷在于降低移动端的crash率,因为在发现崩溃top5内基本上会看到空指针这类错误,但是这类错误也是在服务端异常或者某些特定场景下才会导致某个字段为空或者某类数据为空.

现在客户端处理的流程是,基于业务逻辑加入判空处理.但是这也是见一个问题处理一个问题,并且代码中加入冗余的异常处理逻辑.

前几天读了"美团外卖AndroidCrash治理之路"的帖子,这篇帖子中谈到了对于"crash"预防应该大于治理,提到很多种预防手段.所以我基于这种思想,看看是否能在测试阶段通过自动化手段mock出一些数据,来验证客户端的稳定性和兼容性.

但是如何要想把异常数据测试落地在工作上,其实最难的是如何"说服"开发同学解决这类问题.

代码地址: https://github.com/xinxi1990/mitmfuzz

参考

美团外卖Android Crash治理之路<br> https://tech.meituan.com/2018/06/14/waimai-android-crash.html

在anyproxy上做mock和fuzz测试<br> https://www.testwo.com/article/999

https://github.com/zhangzhao4444/XMonkey

代理服务器 AnyProxy<br> https://www.jianshu.com/p/2074f7572694

https://github.com/fwon/electron-anyproxy<br>

深入了解mitmproxy<br> https://www.cnblogs.com/c-x-a/p/9753526.html

Python实现json数据的jsonPath(精简版)定位及增删改操作<br> https://www.cnblogs.com/shouke/p/10157458.html

App爬虫神器mitmproxy和mitmdump的使用<br> https://cloud.tencent.com/developer/article/1151810

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试加 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 异常数据测试方法
  • 异常数据修改规则
    • 字符
      • 数组
        • 接口超时
          • 接口状态码
            • 增加数据
              • 删除数据
              • 自定义代理
              • mitmproxy
                • mitmproxy安装
                  • mitmweb
                    • mitmdump
                      • 脚本实例
                        • 常用的API
                          • 实例request
                          • 实例response
                        • 设计流程
                          • 定义数据类型
                            • 定义随机事件
                              • 修改字符串
                                • 遍历json
                                • 重新生成json
                              • 数据diff
                              • 效果
                                • UI上展示修改数据
                                  • 类型错误导致崩溃
                                  • 结语
                                  • 参考
                                  领券
                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档