移动测试基础 利用 anyproxy 做 app 网络流量测试

face_south · 2018年03月17日 · 最后由 face_south 回复于 2018年08月30日 · 3825 次阅读
本帖已被设为精华帖!

关于app网络流量测试,通过流量测试可以发现app网络资源使用情况,网络流量也是用户体验中的一项重要内容,同时通过对网络流量数据分析,也可以发现一些app内在的问题。

先翻了一些帖子:

Android 性能测试实践 (四) 流量
Appetizer 优化 APP 网络流量
Android App 持续集成性能测试:启动流量 (1)
[腾讯 TMQ] 常用流量测试方法及一些思考
针对流量测试,大多方法是针对android 应用的测试方法,iOS相关内容较少。
android应用大概有三种测试方法:

  • 通过读取系统文件获取流量数据。获取的数据内容是整体的数据,不便做更进一步分析。
  • 通过android系统提供的API获取。可能需要root权限。
  • 通过其他工具收集信息Appetizer、GT等。
  • 通过代理抓包,wireshark等。 iOS可能最好的办法应该是通过工具、网络代理获取流量信息。

通过代理的方式,可以抓取到明细的数据(请求资源地址、具体资源数据大小等),也方便做后续的具体分析,同时android、iOS应用均实用,不好的一点是对非WiFi情况需要想其他办法处理(顺便提一下iOS可以通过rvictl做,社区也有帖子提到iOS 性能专项初探)。

入主题,本文是通过anyproxy做代理获取流量数据的一些测试尝试

选用anyproxy,主要是用的多了,感觉方便,主要一点是anyproxy的过滤规则机制可以发挥很多作用,了解anyproxy
准备工作:准备测试机,设置代理,安装代理证书等等
anyproxy过滤规则rule.js ,我的过滤规则是讲请求资源地址、请求数据大小、接受数据大小记录到文件,主要内容如下:

module.exports = {

// 获取接口的请求流量
*beforeSendRequest(requestDetail) {
if (requestDetail.url.indexOf("https") === 0) {
url = requestDetail.url;
requestLength = requestDetail.requestData.length;
// requestLength = requestDetail.length;
return null;
}
},

// 获取接口的响应流量
// 存储到文件
*beforeSendResponse(requestDetail, responseDetail) {
if (requestDetail.url.indexOf("https") === 0) {
responseLength = responseDetail.response.body.length;
fs.appendFile(interfaceLog, url + ',' + requestLength + ',' + responseLength + '\n', 'utf8', function(err) {
if(err) {
console.log(err);
}

});
return null;
}
},

}

标注一下:我用的anyproxy版本非最新版,用新版本的可以取response header中的x-anyproxy-origin-content-length字段获取返回相数据大小;还有一点这样的方式获取到数据流量大小与真实数据大小可能略有差异,我只取了一些数据与实际下载时的文件大小做了对比,后续有时间会通过使用多个工具方法等做对比。

拿淘宝android客户端做了一些测试

保存的log文件内容大致如下:

逗号做分隔,资源地址、请求数据大小、返回数据大小,单位是字节数。
然后再读取log文件内容,把信息存入数据库,统计数据库信息做分析。

def read_flow(log):
# 读取anyproxy记录的流量数据计算流量
# path = "/Users/*****"
# filePath = path + log
res = open(log)
requestData = 0
responseData = 0
l = 0
while 1:
line = res.readline()
# print "--line:", line
if not line:
break
l = l + 1
lineList = line.split(",")
resource = lineList[0].split("?")[0]
rex = [r'.*(?:.png|.jpg|.jpeg|.ico|.gif)', r'.*(?:.js)', r'.*(?:.css)', r'.*(?:.html)']
reRes = 0
type = 0
for i in range(len(rex)):
ls = lambda a: re.findall(rex[i], a.split("/")[-1])
if ls(resource):
reRes = i + 1
break
print "resource:", resource, reRes, "|", int(lineList[-2]), int(lineList[-1])
# 插入数据库
try:
start_time = time.strftime("%Y-%m-%d %H:%M:%S")
# insertSql = "insert into flow_2(resource, type, requestData, responseData, total_flow, create_time, tag) ****
# db.query(insertSql)
except:
print u"
sql插入数据库出错"
return

取了三个场景首次启动淘宝并登录、切换淘宝底部的功能栏、查找一件商品添加到购物车并查看我的淘宝部分功能;
网络流量使用数据分别为:3.96902179718、4.89165401459、9.34268379211 单位MB
查询数据库信息,可以清晰的看到流量占用最多的请求,重复请求次数最多的请求,图片、js、css等等具体分类资源的请求数据
例如:
总流量消耗最多

图片流量消耗

js流量消耗

其他资源流量消耗

这样就比较清晰了了解到具体流量消耗数据,哪些消耗最多,哪些频繁请求次数最多等等,再做针对性的分析做处理。

进一步拓展

可以将流量数据收集过程集成到自动化测试的过程中,设置好多个场景,保存不同场景的流量数据信息,做标记,多次测试取基准值,设置好阈值,在自动化测试的过程中,收集信息,超过一定的范围,则预警,也是可以发现一些有问题的功能的;同时anyproxy作为代理工具也可以mock相关数据,为自动化测试提供了方便。

现在做app自动化测试、专项测试的那么多,你们是怎么做的?

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 24 条回复 时间 点赞
seveniruby 将本帖设为了精华贴 03月18日 09:26

咱两名字一样,给你点个赞😂

学习了。感觉像探索性测试 ,专项测试收集数据是一部分 分析数据才是大头。没有看到楼主分析数据有些可惜

@bob_jie 我这边的app内嵌的webview,对统计到的数据,分别统计js、图片、css、api等流量消耗占比,再具体看某一类中的重复请求次数、流量消耗排名,有一些js、图片占用流量一次测试中多达十几兆,很明显是不合理的,后边去定位这些较高消耗项的具体问题,为什么本身流量用的多,为什么重复获取资源次数多, 针对依据什么样的标准判断流量消耗多需要处理,这个我的想法是总流量占比排名前10,再删选重复请求资源次数排名前10的再去针对分析,可能这样的办法也不够成熟。

rule.js 文件在哪里修改

@chunyong 过滤规则文件是自己写的,启动anyproxy的时候加--rule来使用过滤规则文件 anyproxy --intercept --rule ~/Documents/job/rule.js

@face_south 已经搞定了。多谢,想问一下,最后那个数据:请求次数是通过最后的sql语句整理的把?

@chunyong 是的 sql

@face_south 方便看下mysql 建表的一些字段吗

@chunyong 文章代码里边有的 resource, type, requestData, responseData, total_flow, create_time, tag 大概就这些 自定义吧

@face_south 想问一下 为什么同一个文件请求了那么多次,而且每次返回数据大小还不一致,如同你上面图里面的.zip 和.png。 这个是由于什么原因导致的呢?

@chunyong 有几个zip的上传的打包数据,我猜可能是记录的埋点信息内容,这个肯定不是每次大小都一致的;png大小不一致,本身请求的资源也不一样;这边的app有个情况,用到react native,然后每个页面都是打包好的一个js而且名称都一样,js占用的流量占比最大,可能和rn的机制有关系,具体不是很了解。

@face_south 没太明白您说的,比如一张.png图片,连续请求了3次,而且每次接受数据大小还不一致。这是什么问题导致的?

@chunyong 同一张图片 连续请求三次大小不一致 没有遇到 你有链接可以直接下载一下对比数据对不对,还有一点就是请求的方式是不是不一样,get请求,option请求。


这个第一个图片不就是请求了3次吗? 三次的请求大小是一样的吗?

@chunyong
查了下我数据库的记录,是有三次请求每次的数据大小是不一致的,因为这是淘宝客户端的数据信息,我没有具体跟是什么情况,后续等我有时间我也再观察看看(如果是记录的数据本身有问题就尴尬了)。

@face_south 不是你记录的问题,我这边测试的时候也出现了这个问题,暂时还不知道是什么原因,比较疑惑。

用这个方法测试发现好多不准确的地方,第一是:同一张图片请求次数的问题,第二:我在软件管家里面下载了一个200MB的游戏app,给我输出请求和返回的流量大小都为0; 纠结。

21楼 已删除

@chunyong 你可以这样 过滤规则文件再丰富一下,记录请求的url 请求方式 请求数据 返回数据写到log文件中,这样你看看log内容记录的有没有问题。

麻烦问下js怎么写入到本地txt文件中

@xinxi1990
过滤规则文件可以这么写

var fs = require("fs");
var logFile = "/*/*/log.log";

module.exports = {

*beforeSendResponse(requestDetail, responseDetail){
// 请求数据
const urlRequest = requestDetail.requestData;
// 返回内容
const urlResponse = responseDetail.response.body;
// 可以写入时间点信息
// 写入文件 格式自己整理
fs.appendFileSync(logFile, " \nurl: " + requestDetail.url + "\n" + "request:" + urlRequest +"\n"+ "response:"+urlResponse, 'utf-8', function (err) {
if (err) throw err;
console.log('data is saved!');
});
}
}

@face_south 您好,我这边用了下,不生成log文件

@plateau520 检查代理设置好了吗 log地址写的有没有问题,看看输出的内容里边有没有报错信息

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册