App稳定性测试

https://www.notion.so/App-0d9ed025434348d68700a8c30ac704f4

现在App普遍可以运行在后台,在用户切换到的时候唤醒到前台,一方面可以避免不必要的冷启动时间,另一方面可以持续接收服务端的推送。前后台运行时间加起来可以长达几十小时,甚至几百小时,所以对于App长时间使用的稳定性有了更高的要求,需要App稳定性测试来避免长时间运行下的偶发闪退、内存泄露、性能变差等等。通常App稳定性测试采用Monkey类的工具来长时间全自动遍历App,并捕获期间发生的稳定性问题。综合各个Monkey方案的稳定性、可配置性、执行效率等多方面考虑,首选Maxim作为Monkey遍历工具,通过Appetizer管理和配置Maxim提高方案试错效率。稳定性测试方案有以下重点,本文将一一解答:

  • 如何配置Maxim提高遍历效率
  • 如何评估自动遍历的覆盖率以及遍历时间
  • 稳定性测试要捕获什么,可以捕获什么
  • 如何复现捕获的问题/提稳定性Issue
  • 如何拓展稳定性测试,让同样的测试时间产出更大

基础知识

Google 原生Monkey 是一个命令行工具,可以全自动随机点击屏幕,用来测试App稳定性等。Maxim 是 @zhangzhao_lenovo 修改自 monkey的高级版本,支持 Android 5.0-9.0、操作非常高速 (10-15事件/秒),稳定性高,可配置。 AppetizerIO提供了对Maxim的深度集成,使得配置更方便,配置管理更简单。从Appetizer导航 -> 自动化测试 -> Maxim,最基本配置选好测试设备和测试APK即可开始测试。Maxim提供的配置有:

  • Maxim的遍历模式,如图

    https://testerhome.com/uploads/photo/2019/60e027f7-ac15-4303-8fbd-74e48cae6fba.png!large

  • Activity黑白名单,选择待测APK后会出现选择,下文有截图

  • 测试时长,可以根据时间(分钟)或者自动产生的事件数

  • max.xpath.actions 指定界面确定性步骤,例如登录

  • max.widget.black 屏蔽某些界面的某些控件或者区域,例如屏蔽广告区域

  • max.config 开启定时截图;调整启动等待时间

  • 事件间延迟:两次事件间隔的时间

  • Maxim事件日志

  • 数据采集和输出路径:Appetizer可以在测试过程中收集额外数据,例如Maxim日志、logcat,Battery Historian数据等等

如何配置Maxim提高遍历效率

由于Monkey本质上是无脑交互,在实际使用中,很容易由于进入了一些App场景后在里面转悠几十分钟都出不来,大大影响了遍历效率。以下经验和大家分享:

  1. 不要从全新安装的App安装开始遍历 很多人的方案开头就是自动adb安装App,其实这样效果很差,因为全新安装后会出现大量的低频新手教程、登录、权限弹框等影响Maxim。而稳定性测试本质上是模拟老用户长时间使用App的情况,所以应当已经完全登录,新手流程已经全部过掉的情况下再开始Maxim。具体实施的时候有几种选择:a. 手工安装app,登录,过掉已知的新手教程 b. 始终不清除稳定性测试设备上app的数据,较新的开发版App可以更新安装保持数据 c. 如果b不容易实现,可以试试 adb backup 和 adb restore 保存和复原 App数据

  2. 避免动态权限弹框 动态权限弹框也是影响Maxim执行的很大因素,各个厂商弹框不同,很难适配。因此在开始Maxim遍历前,应当赋予App所有需要的权限,这步可以手工,也可以用adb pm grant <包名> <权限名>来自动实现。

  3. 关掉输入法 遍历过程中无可避免会点击到各种输入框,输入法会弹起,一旦Maxim点击到输入法,例如某狗,某度输入法,会导致非常多不可预料的情况,比如输入法广告弹框,录音弹框等等。而且Maxim遍历时如果要输入内容,也是直接输入并非通过输入法,所以输入法是一个纯干扰,最简单的方式就是在开始遍历前关掉输入法,结束后再开启。具体实现时,安装Appium Keyboard(也就是啥也没有),然后 通过adb shell ime 来设置输入法

  4. 黑名单屏蔽Activity和控件Maxim提供了两个级别的禁止遍历黑名单,可以通过配置直接禁止进入某些Activity,也可以通过配置屏蔽指定Activity上的区域(xpath或者坐标范围)。Activity黑名单原理是截获切换的Intent直接不发,Appetizer提供的图形化方案可以非常简单地设置Activity黑名单:屏蔽的规则很简单,一般屏蔽一切非App业务的第三方推送、第三方支付、第三方登录、分享、扫码、人脸识别、图片/文件选择器、人工客服。而区域屏蔽则更为精细,应当屏蔽三方登录按钮区域、付费选择、广告、分享按钮等一切能够切出App或者需要人工/摄像头的功能点。登录和支付业务不应该在稳定性测试中出现,应该是登录专项和支付业务用例里。max.widget.black配置项是一个数组,每一项一条屏蔽规则,规则很容易懂,指定某个Activity以及需要屏蔽的控件的xpath,或者屏幕像素区域bounds或者有多个符合xpath条件的控件条件下增加index表示第几项

    https://testerhome.com/uploads/photo/2019/f85e864e-ea64-4ad5-8031-07121cee0a99.png!large

    https://testerhome.com/uploads/photo/2019/7fb4d171-2725-4beb-883c-ab081a10c08c.png!large

  5. 调整事件比例Maxim MIX模式下默认会有30%完全随机事件(屏幕任意位置乱点、滑动、任意物理按键) + 70%界面元素解析后的元素级交互,在用于App稳定性测试过程中,比例应当根据App特性进行调整。Maximw从Google原生Monkey改来,完全兼容Monkey的参数,如下:

    • --pct-touch <percent> 为单击事件百分比

    • --pct-motion <percent> 为滑动事件百分比(方向、长度和速度随机)

    • --pct-trackball <percent> 随机滚动后点击事件百分比

    • --pct-nav <percent> 上下左右滑动事件

    • --pct-majornav <percent> 回退、home、最近三键

    • --pct-syskeys <percent> 系统按键,标准三键+音量等

    • --pct-appswitch <percent> 切换App 实际使用中,非0项目应该为 --pct-touch --pct-motion --pct-majornav,其中touch可以低一些,因为毕竟有元素级别touch乱点没有特别大的意义;motion可以高一点,弥补Maxim不会滑动的缺陷;majornav中等,保证有一定量的回退;推荐使用5,20,10;

      https://testerhome.com/uploads/photo/2019/0b9993cf-7ca1-40d8-97ce-c9c43956b26a.png!large

  6. 多个配置结合配置不可能一蹴而就,也不用纠结在单个配置上。可以分几次跑,每次入口的Activity不一样,然后参数不一样来达到综合做好的情况。例如主界面有多个主业务入口,可以每个主业务入口Activity用一套配置,每套配置里面把主界面黑名单掉,这样就不会回退回来。Appetizer存取多个配置:

    https://testerhome.com/uploads/photo/2019/56a56a81-58d5-496f-9fa1-cb0a17959c62.png!large

  7. 处理表单类界面表单类界面即有多个输入框,然后按钮,而按钮成功要求多个输入框满足一个验证条件,例如都要有内容。表单类界面是Maxim和Monkey类工具非常不适合的一种界面,随机能够满足验证条件的概率极低,基本没有探索价值。可以直接黑名单,或者通过 max.xpath.actions 配置项直接填写。

    https://testerhome.com/uploads/photo/2019/d0ff280f-eb71-4e7d-a5d6-f67146bf485d.png!large

如何评估自动遍历的覆盖率以及遍历时间

覆盖率大致方向有两个,Jacoco(代码行覆盖)和Activity覆盖率,Jacoco需要 源代码接入,完全落地需要一定时间。在配置初期,并不用太强调代码行覆盖率,毕竟Maxim有一定的随机性,多次跑可能导致不同的结果。在配置初期,可以以Activity覆盖率作为主要参考,力求尽量覆盖到可以自动化遍历的业务Activity。Activity覆盖率获取方式有两种:如果APK经过Appetizer插桩,每次Maxim运行后都会有Appetizer插桩数据报告,里面有Activity覆盖率以未覆盖的Activity名单;如果没有插桩,可以用Appetizer保存Maxim运行产生的stdout,然后自行parse进入过的Activity。

https://testerhome.com/uploads/photo/2019/e96a1123-d91c-4877-9439-242f2804a502.png!large

当配置优化后,同时Jacoco方案已经成熟的情况下,可以评估一次完整的稳定性测试的代码行覆盖情况。一般来说行覆盖率不会很高,原因有几个部分 1. Jacoco统计分母是所有的class,有很多三方代码和库代码是dead code实际不会执行,除非Jacoco分析的时候就去掉的这些 2. 毕竟Maxim遍历没有逻辑性,很多和数据相关的代码块并不能有效进入 3. 单机型运行的话,有些安卓版本特殊的代码也会遗漏;总体来说,行覆盖仅仅做参考,配置优化能增加就是好事,不必苛求一个具体百分比目标。

遍历时间并不是越长越好,因为执行初期对覆盖率提升非常有效,而后期大量的时间对两种覆盖率的提升都是非常有限。另一方面来说,遍历时长太久大大增加了收集到的数据量,影响分析效率,也会引入不必要稳定性坑。应当多花费时间优化配置,帮助Maxim省去非常多的不可控性和徒劳遍历,一般一套优化过的配置,只需要20分钟到1个小时即可。

稳定性测试要捕获什么,可以捕获什么

  1. crash, ANR

    • Maxim会自动log疑似App crash的情况,结果将保存在 /sdcard/maxim-output/crash.log,注意这些只是疑似情况
    • Appetizer插桩后的App会捕获crash ANR,在报告中
  2. 主线程卡顿

  3. http 请求4xx 5xx,以及高延迟的情况

  4. 截图Maxim支持每次执行事件后截图,还支持保存页面控件结构(XML),截图上会有事件点击的红点标注,方便发现问题后回溯到具体场景,具体字max.config里开启,如下图。注意,截图保存在 /sdcard/max-output 目录,长时间运行会占据大量的存储控件,确保每次运行前用Appetizer下载上次的截图结果,并删除

    https://testerhome.com/uploads/photo/2019/e26cc137-3ba8-44f0-9299-a2829b73a743.png!large

如何拓展稳定性测试,让同样的测试时间产出更大

很多时候第一次引入稳定性测试后会发现一些问题,积极性会比较高,随着时间推移,问题会发现越来越少,换个方面考虑是App低级错误越来越少,这时候会面临继续投入稳定性测试的质疑,这方面有几点:

  1. 稳定性测试和回归是一样的,是守门员,非前锋,目标是拦截不是预言,
  2. 自动遍历其实会高速发出UI事件,对App性能也是一个考验,所以自然可以收集并分析性能数据,在稳定性测试的框架上分析性能瓶颈。
posted @ 2021-01-19 10:49  蒋励  阅读(991)  评论(0编辑  收藏  举报