移动性能测试 Android App 持续集成性能测试:启动流量 (1)

debugtalk · 2016年05月03日 · 最后由 robin1008 回复于 2016年08月16日 · 3891 次阅读

本文对 Android App 的启动流量测试进行介绍。这里的启动流量指的是网络流量,即 App 在启动时发起网络请求和接收网络响应时传输的网络数据量。

说起流量,也许大家的第一反应就是 tcpdump/wireshark 这类网络抓包工具。的确,Android 系统确实也支持tcpdump工具,通过tcpdump,我们可以实现非常精准的流量测试。但tcpdump也有个问题,就是它捕捉到的流量是系统层面的,我们很难区分捕捉得到的流量数据是否都是当前 apk 产生的。

其实,对于特定 apk 的整体流量数据,在 Android 系统中都会存储到对应文件中,我们完全可以通过读取对应文件来获得当前 apk 的流量信息。

get app UID

与流量相关的状态数据存储在/proc/uid_stat/<UID>/目录下,其中,<UID>表示 apk 对应的 UID。

关于 UID,简单地进行下说明。在 Linux 系统中,UID 表示的是 User Identifier,主要用于表示是哪位用户运行了该程序。但在 Android 系统中,由于 Android 系统本身就为单用户系统,这时 UID 就被赋予了新的使命,主要用于实现数据共享。具体地,Android 系统为每个应用都分配了一个 UID,不同 apk 的 UID 几乎都是互不相同的,而对于不同 UID 的 apk,不能共享数据资源。之所以用 “几乎”,是因为有时候同一厂家会存在多个产品,并且希望能在多个 apk 之间实现数据共享,这个时候,便可通过在 menifest 配置文件中指定相同的 sharedUserId,然后在 Android 系统中安装应用时便会分配相同的 UID。

获取 app UID 的方式有多种,最简单的方式应该还是从/data/system/packages.list中读取,并通过 apk 的<PKGNAME>找到对应的 UID。

root@hammerhead:/ # cat /data/system/packages.list | grep com.UCMobile.trunk                   
com.UCMobile.trunk 10084 0 /data/data/com.UCMobile.trunk default 3003,1028,1015

在这里,10084 即是com.UCMobile.trunk的 UID。

获取流量数据

流量数据分为接收流量(tcp_rcv)和发送流量(tcp_snd)两部分,这两个状态数值我们可以通过读取/proc/uid_stat/<UID>目录下的两个文件得到。

shell@hammerhead:/ $ cat /proc/uid_stat/10084/tcp_rcv                          
3446837
shell@hammerhead:/ $ cat /proc/uid_stat/10084/tcp_snd                          
134366

通过这种方式,我们就可以读取得到指定 apk 在当前时刻的累计流量数值。

获得启动流量数据

有了前面的基础,我们要测试启动流量就很好实现了。只需要在启动前采集下累计流量数值,然后启动应用,完成启动后再采集一次累计流量数值,前后两次累计数值的差值便是当次启动耗费的流量数。需要注意的是,由于很多时候 apk 在启动后,会在系统后台异步加载一些数据资源,因此为了保证我们采集到当次启动耗费的全部流量数值,我们在启动应用后最好能等待一段时间。

root@hammerhead:/ # cat /proc/uid_stat/10084/tcp_snd                           
15068
root@hammerhead:/ # cat /proc/uid_stat/10084/tcp_rcv                           
98021

# start app activity, sleep 10s

root@hammerhead:/ # cat /proc/uid_stat/10142/tcp_snd                           
23268
root@hammerhead:/ # cat /proc/uid_stat/10142/tcp_rcv                           
965651

采集到前后两次流量数值后,即可计算得到当次启动耗费的总流量。

当次启动总流量 = (23268 + 965651) - (15068 + 98021) = 875830 bytes

当然,这里的启动还分为好几种,包括首次安装启动、非首次安装启动、覆盖安装启动等。具体的启动方式可根据实际场景来定,但在统计流量的方法方面都是相同的。

总结

本文讲解了 Android App 启动流量测试的一种方法。然而,本次介绍的方法也存在一定局限性,因为/proc/uid_stat/<UID>/目录下的tcp_rcvtcp_snd文件中都只记录了总值,如果我们只关注总体的流量数值还好,但要是我们希望能测试得到更细化的数据,该方法就没法满足我们的测试需求了。

举个例子,UC 浏览器国际版在启动后,会和美国的服务器进行通讯交互。现在,我们想测试 UC 浏览器国际版在启动后与美国服务器的通讯流量。

显然,本文中介绍的方法是没法实现上述例子中的测试需求的。那例子中的场景要怎么测呢?这就还是得用到tcpdump,在下一篇文章中我会再详细进行介绍。

Read More ...

微信公众号:DebugTalk
原文链接:http://debugtalk.com/post/Android-performance-test-start-traffic-uid-stat/

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 19 条回复 时间 点赞

有时间试试,我之前用的是'adb shell cat /proc/pid/net/dev | grep wlan0'这个方法获取的流量,每次都要清空数据,并且杀掉其他所有可能会使用流量的进程,有点麻烦。感谢分享!!

不过有一个问题想请教一下,如果这个 APK 是首次安装,那么这样通过 PID 获取会不会出问题?首次安装的 APK 好像没有 PID,不知道我有没有记错

上次我用的是这个。

# net user calc
net_user_info = ex_cmd(
    'adb -s %s shell cat /proc/net/xt_qtaguid/stats |%s %s' % (pkg_info['UDID'], GREP, pkg_info["userId"]))
if len(net_user_info) > 0:
    rx_b = 0
    tx_b = 0
    for xx in net_user_info:
        all_net = xx.split()
        rx_b += int(all_net[5])
        tx_b += int(all_net[7])
    rxtx = rx_b + tx_b
    other_result['Network_rx'] = rx_b
    other_result['Network_tx'] = tx_b
    other_result['Network_all'] = rxtx

到底哪个准啊。

#1 楼 @wyb199026 在这篇文章中,没有用到 PID 啊,只用到了 UID,这个跟 app 是否启动没关系的

#2 楼 @among29 这种方式我没有用过,可以对比下两种方式的结果哦

#3 楼 @debugtalk 噢噢噢,我看错了

/data/system/packages.list 貌似需要 root 权限,以下方式也可,获取前台程序流量消耗 (批处理)
:getNetInfo
for /f "tokens=2 delims=/ " %%a in ('adb shell dumpsys activity top|findstr "ACTIVITY"') do set packageName=%%a
for /f "tokens=2 delims=/}" %%a in ('adb shell dumpsys package|findstr packageSetting|findstr %packageName%') do set uid=%%a
echo "%packageName% Uid is:" %uid%
for /f %%a in ('adb shell cat /proc/uid_stat/%uid%/tcp_rcv') do set /a rcv=%%a/1024
for /f %%a in ('adb shell cat /proc/uid_stat/%uid%/tcp_snd') do set /a snd=%%a/1024
echo 下行流量:%rcv% Kb
echo 上行流量:%snd% Kb

楼主贴文章, 尽量不要放二维码. 放链接也是可以的.
根据经验. 凡是贴二维码的. 基本都是营销号...

#6 楼 @fresh 嗯嗯,通过 dumpsys 获取 uid 也是一个办法

#7 楼 @seveniruby 思寒大大,我详细阅读了论坛须知,并没有这方面的限制,而且也在留言中和恒温确认过,放二维码是允许的。

至于 DebugTalk 这个公众号,这只是我自己用心在做的一个个人公众号,相当于个人博客的另一种形式,并没有想过以此导流进行营销,还请思寒大大明鉴。

很好的文章

#10 楼 @sunny1111 多谢鼓励

cat /proc/uid_stat 请问下我的测试机的/proc 目录下没有 uid_stat 这个文件如何查看呢?网上了解到可能是手机厂商隐藏了...

#12 楼 @chaner2014 获取 uid 的方式有很多,没有/proc/uid_stat 文件的话就只能尝试用别的方式获取 uid 了,例如@fresh 提供的方法,采用 dumpsys 也能获取 uid 的

#14 楼 @nateby 其实还是流量测试,只是侧重于启动过程中的流量

内容不错

为什么我/proc/uid_stat/下面没 tcp_rcv 和 tcp/snd 啊

谢谢分享

写的很清晰,评论区也有很多其他的好方法,学习了👍

向阳 利用 anyproxy 做 app 网络流量测试 中提及了此贴 03月17日 14:15
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册