移动分发市场竞争已进入炽热化,已不再是当年野蛮生长阶段。各大分发市场都在走精细化与差异化路线。其中,省流量更新 (增量更新) 成为提升用户体验,增加用户留驻粘性的一项重要指标。所谓增量更新是指 app 可以通过增量 apk 的方式进行更新,而不用每次都下载应用全量 apk 包,该技术可以大大提升 app 升级效率,提升用户体验。
基于以上的背景和考量,应用宝测试团队,进行了增量更新监控专项,监控自己的增量更新能力。下面撰文,简述流程与技术栈,以飨读者。
省流量更新在本文中按照业界术语统称为——“增量更新”。
该增量更新监控,旨在监控实际热门 app 的增量更新指标(包括是否有增量更新,更新包大小,更新下载速度等),同时监控增量更新下载阶段的 CPU,内存是否有异动。
根据市场表现,在 PC 开发机上,从应用宝市场,批量自动获取 top100(最活跃下载 app)作为待测 app。然后 100 个 app 循环,依次推送并安装到指定测试的安卓手机至上,并使用 UI 自动化技术作为按键控制和 app 页面元素监控,成功获取是否增量更新以及增量更新大小和相关合成/下载速度等指标。与此同时,测试机端上同步开启 CPU,内存等多维度监控手段,并存储到本地 sd 卡中,更全面衡量监控期间应用宝的增量更新相关指标。测试完毕,将本地 sd 卡存储的相关指标数据,推送回 PC 端开发机,结合自动脚本实现结果分析与处理,最终结果讲入数据库存储,并提供 WEB 端展示相关结果。监控流程自动实现。
下文是增量更新监控方案图:
接下来,将以单元方式展开主线叙述。包括——UI 监控 (UIAutomator 端上监控)、CPU 监控、内存监控、数据分析处理与结果展示。
主要涉及:
(1)UI 监控:java,UIAutomator;
(2)CPU,内存监控: 安卓底层数据获取,java;
(3)数据分析处理与结果展示:python,numpy,Django 框架。
我们在应用宝上批量获取典型热门 top100 app 作为待测对象。然后在测试机上进行增量更新监控。
先来确定下 UI 监控框架。端上 UI 自动化框架较多,如 Appium、Robotium 等,本次工程我们我们采用 UIAutomator。UIAutomator 是为数不多的安卓官方支持的自动化框架之一。其 API 简明而高效,被广大测试同学所钟爱。尤其 UIAutomator 非常适合 App 间协作所需的跨进程测试,本专项正是此场景。
UI 监控部分使用 Android Studio 和 UIAutomator 开发,基于篇幅限制,作者默认读者已有对工具和框架已有了解,新人请参见 TMQ 已有介绍 Android Studio 和 UIAutomator 使用的文章,本文不再复述。
UIAutomator 扫描精度默认是 1000ms,而增量更新对时间精度要求严格,希望达到百 ms 级别。所以,需要通过反射更改底层扫描间隔,即 WaitMixin 类中的 DEFAULT_POLL_INTERVAL,其被定义为 private static final long DEFAULT_POLL_INTERVAL = 1000; 经笔者实践,在本项目场景中,DEFAULT_POLL_INTERVAL 为 200 是其精确上限,故而采用 200ms 作为 UIAutomator 扫描间隔精度。
反射机制部分核心代码:
该专项中 UI 操作主要分为几类:
(1)模拟按键
主要是应用市场调起后,模拟人类按键,使得进行相关测试操作。如进入应用市场后,根据 resource-id, 来点击 “管理” 按钮,下图是操作实例。下图模拟点击” 管理”。
核心代码如下所示:
(2)获取页面元素的值
我们可以通过 resouce-id,来获取页面元素的值。如图所示,在应用宝中,可以看到测试手机自带的豌豆荚软件是旧版本的,且在应用宝市场是存在增量更新的。我们可以通过获取 resouce-id 的 value 来判断是否有增量更新以及增量更新包的大小。
如下是核心代码实现,仅供参考:
(3)状态检测
上图步骤中,点击” 省流量更新”,即可进入增量更新下载增量包阶段。检测进度条尾端的状态栏,进度条满且状态值为 100% 更新下载结束。这一段时间,是时间的增量更新时间,之后按钮会变为 “合成中”。由于 100% 出现的时间极其的短暂,所以,终止态采用 “合成中” 出现时间作为终止态。
代码片段示意:
上文相关操作,最后将待测 app 在分发市场上是否有增量更新,增量大小,更新 时间,记录在 SDCARD 并推送到 PC 端聚合汇总。
增量更新期间,我们会关注应用市场的内存增长情况,以期更好更全面评价性能指标。所以,UI 监控同时,我们还在测试机上进行了内存监控和 CPU 监控,监控增量更新下载期间是否有异常强情况。
由于安卓内核是剪裁的 linux 基本核。所以,安卓内存底层数据规律和 linux 是一致的。笔者研究了其内存机制,并找到了一种合适的监控方法。先说操作,再讲原理。
Adb shell 登录安卓测试机:
PS 应用名,得到 pid(进程 ID)。
红色方格为进程 ID。
cat/porc/PID/status 可以得到详细的内存情况。如下图所示:
各个字段的含义:
VmPeak:表示进程所占用最大虚拟内存大小
VmSize:表示进程当前虚拟内存大小
VmLck:表示被锁定的内存大小
VmHWM:表示进程所占用物理内存的峰值
VmRSS:表示进程当前占用物理内存的大小 (与 procrank 中的 RSS)
VmData:表示进程数据段的大小
VmStk:表示进程堆栈段的大小
VmExe:表示进程代码的大小
VmLib:表示进程所使用共享库的大小
VmPTE:表示进程页表项的大小
在本专项中,VmRSS 字段即为我们所需要的内存大小。通过 java 实现该脚本,并集成在 UIAutomator 工程之中,按时间间隔调用即可实现按间隔调用。所获取数据记录到测试手机 SDCARD 之中,监控测试结束推送到 PC 端聚合。当然,也可以 top 来找内存信息,不过其精度较差并且刷新有滞后性,所以,建议以本文的方式来获取进程的内存消耗情况较好。
同 4,基于安卓出自于 linux 剪裁的先天条件,我们依然可以从 linux 底层找 CPU 的监控规律。当然,我们也可以用 top 来测试手机上看 cpu 使用情况。
不过,我们还是希望能更专业一些,去从底层数据,更精准的衡量 CPU 规律。
/proc///stat, 包含了所有 CPU 的相关详情信息。
该文件中的所有值都是从系统启动开始累计到当前时刻。CPU 不是一个瞬时态,而是一个过程态的体现,这一点和内存不同,大家要清楚明白。CPU 的时间计数单位是 jiffies,为 Linux 核心变数 (unsigned long),它被用来记录系统自开机以来,已经过了多少 tick。每发生一次 timer interrupt,Jiffies 变数会被加一。我们利用 process jiffies 的消耗,来计算 CPU 值。即 Delta T 时间段内消耗的平均 jiffies,即为该时间范围内的 CPU 值的大小。下图是获取某一时刻的 CPU 详情。
我们所需要的 process jiffies,具体是/proc//stat 文件的第 14-17 列。14-17 列分别是 utime, stime, cutime, cstime。cutime/cstime 分别是该进程 spawn 的子进程在用户态和内核态消耗 jiffies。
process jiffies = utime + stime + cutime + cstime
注意 stat 中的 jiffies 是一个绝对累计值,所以要取两个时间点,算 Delta T 中消耗的 jiffies。(cpu value)= ((current process jiffies) - (last process jiffies) )*100%/(Delta T )。
综上所述,我们在 T1,T2 时刻分别/proc///stat,然后提取出 process jiffies 并与 |T1 -T2| 做商,即可获取该时间段内的 CPU 使用情况。本专项中,采用 5S 的时间间隔,时间太短会影响 CPU 的真实值,因为抖动毛刺的缘故。
应用宝增量更新监控做完之后,我们利用 python 科学计算库 numpy 处理下文件。总共 100 个 app,计得 100 份文件结果,对结果进行清洗和过滤(去异常和脏数据),之后得到详情数据和最总指标数据,并将结果入库。
得到 mysql 中的结果后,为了直观展示与管理,我们将统计数据以直观的形式 WEB 展现出来。WEB 采用 Django 框架。
最后得到我们需要的结果。结果如下所示:
本文以应用宝增量更新监控为例,向广大读者提供几点借鉴。
1、UIAutomator 框架的监控使用方法;
2、安卓 CPU 和内存的监控方法。
本文除了介绍 andorid 的 UI 监控,还介绍了内存,cpu 管理原理与监控方法。引申一下,如果要做 android 的 IO 监控和网络监控,应该怎么做呢?
关注微信公众号腾讯移动品质中心 TMQ,获取更多测试干货!