Monkey自动化测试

Monkey概念介绍

Monkey是猴子的意思。Monkey测试,就像一只猴子,在电脑面前,乱敲键盘在测试。猴子什么都不懂,只知道乱敲。

Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试。

Monkey命令

Monkey基本语法

adb shell monkey [options]
如果不指定options,Monkey将以无反馈模式启动,并把事件任意发送到安装在目标环境中的全部包。

Monkey常用命令

1,-help 列出简单使用指南。
如:adb shell monkey -help

2,-v 每增加一个-v都将增加反馈信息的详细级别。
如:adb shell monkey -v -v -v 100
表示执行100个伪随机用户事件流,并提供了测试中所有相关Activity信息。

Level 0(默认),除了启动、测试完成和最终结果外只提供较少的信息。
Level 1,提供了较为详细的测试信息,如逐个发送到Activity的事件信息。
Level 2,提供了更多的设置信息,如测试中选中或未选中的Activity信息。

3,-s < seed> 伪随机数生成器的种子值。如果你用相同的种子值重新运行Monkey,它将生成相同的事件序列。
如:adb shell monkey -s 1123 表示重现种子值为1123的事件序列。

4,-throttle < milliseconds> 在事件之间插入固定延迟。通过这个选项可以减缓Monkey的执行速度。如果不指定该选项,Monkey将不会被延迟,事件将尽可能快地被产成。
如:adb shell monkey -throttle 300 -v 100 表示执行100个伪随机用户事件流,事件间隔为300毫秒。

注:一般设置为300毫秒,原因是实际用户操作的最快300毫秒左右一个动作事件。

5,-pct-touch< percent> 表示调整触摸事件的百分比(触摸事件是屏幕上单个位置的down-up事件)。
如:adb shell monkey -pct-touch 67 -v 10
表示执行10个伪随机用户事件流,并调整其中触摸事件的百分比为67%。

注:此参数设置要适应当前被测应用程序的操作,比如一个应用80%的操作都是触摸,那就可以将此参数的百分比设置成相应较高的百分比。

6,-pct-motion < percent> 表示调整动作事件的百分比(动作事件由屏幕上某处的一个down事件、一系列的伪随机事件和一个up事件组成)。
如:adb shell monkey -pct-motion 67 -v 10
表示执行10个伪随机用户事件流,并调整其中动作事件的百分比为67%。

注:这里的移动是直线滑动,下面的trackball移动包含曲线移动。

7,-pct-trackball < percent> 表示调整轨迹球事件的百分比(轨迹球事件由一个或多个随机移动组成,有时还伴随有点击)。
如:adb shell monkey -pct-trackball 67 -v 10
表示执行10个伪随机用户事件流,并调整其中轨迹球事件的百分比为67%。

8,-p < allowed-package-name> 表示如果用此参数指定了一个或几个包,Monkey将只允许系统启动这些包里的Activity。如果你的应用程序还需要访问其它包里的Activity(如选择取一个联系人),那些包也需要在此同时指定。如果不指定任何包,Monkey将允许系统启动全部包里的Activity。要指定多个包,需要使用多个 -p选项,每个-p选项只能用于一个包。
如:adb shell monkey -p com.jzf.simple1 -p com.jzf.simple2 100
表示对包“com.jzf.simple1”和“com.jzf.simple2”执行100个伪随机用户事件流。

9,-c < main-category> 表示如果用此参数指定了一个或几个类别,Monkey将只允许系统启动这些指定类别中列出的Activity。如果不指定任何类别,Monkey将选 择下列类别中列出的Activity: Intent.CATEGORY_LAUNCHER或Intent.CATEGORY_MONKEY。要指定多个类别,需要使用多个-c选项,每个-c选 项只能用于一个类别。

10,-ignore-crashes 表示当应用程序崩溃或遇到任何类型的未处理的异常时,Monkey将停止。如果指定此选项,则Monkey将继续向系统发送事件,直到计数完成。

11,-ignore-timeouts 表示当应用程序遇到任何类型的超时错误(如“应用程序无响应”对话框)时,Monkey将停止。如果指定此选项,则Monkey将继续向系统发送事件,直到计数完成。

12,-ignore-security-exceptions 表示当应用程序遇到任何类型的权限错误时,Monkey将停止,例如,如果它尝试启动需要某些权限的活动。如果指定此选项,则Monkey将继续向系统发送事件,直到计数完成。

13,-kill-process-after-error 当Monkey由于一个错误而停止时,出错的应用程序将继续处于运行状态。当设置了此选项时,将会通知系统停止发生错误的进程。注意,正常的(成功的)结束,并没有停止启动的进程,设备只是在结束事件之后,简单地保持在最后的状态。

14,-monitor-native-crashes 表示Android系统原生代码中的监视和报告崩溃。如果设置了-kill-process-after-error,系统将停止。

15,-wait-dbg 表示停止执行中的Monkey,直到有调试器和它相连接。

16,adb shell -p com.jzf.simple -v -v -v 100 > monkey.txt
表示日志保存在系统目录的monkey.txt文件下

17,adb devices 查看设备是否连接成功,如果有手机串号说明连接成功。

18,adb shell pm list packages 表示查看手机内所有的包名。

Monkey日志分析

在执行随机事件流之后,终端会显示一组日志信息。比如你执行以下代码:
adb shell monkey -p your.app.name -v -v -v 500 表示对你的APP执行500个伪随机事件流并将反馈信息级别设置最高。

由于篇幅原因,这里简要列出一些日志进行说明。(//注:这里是事件说明)

jzf:~ jinzifu$ adb shell monkey -p com.zjrb.sjzsw -v -v -v 2
:Monkey: seed=1509666218694 count=2 //注:monkey执行的seed值和随机事件次数
:AllowPackage: com.zjrb.sjzsw //注:可以执行的包名
:IncludeCategory: android.intent.category.LAUNCHER
:IncludeCategory: android.intent.category.MONKEY //注:默认执行的activity的category类别
...
// Seeded: 1509666218694
// Event percentages: //注:分配事件的百分比,事件号对应如下
//   0: 15.0% //注:触摸事件百分比,即参数--pct-touch
//   1: 10.0% //注:手势事件百分比,即参数--pct-motion
//   2: 2.0% //注:缩放事件百分比,即参数--pct-pinchzoom
//   3: 15.0% //注:轨迹球事件百分比,即参数--pct-trackball
//   4: -0.0% //注:屏幕旋转事件百分比,即参数--pct-rotation
//   5: -0.0% //注:基本导航事件百分比,即参数--pct-nav
//   6: 25.0% //注:主要导航事件百分比,即参数--pct-majornav
//   7: 15.0% //注:系统事件百分比,即参数--pct-syskeys
//   8: 2.0% //注:Activity启动事件百分比,即参数--pct-appswitch
//   9: 2.0% //注:键盘翻转事件百分比,即参数--pct-flip
//   10: 1.0% //注:其他事件百分比,即参数--pct-anyevent
//   11: 13.0% //注:?
...
:Sending Touch (ACTION_DOWN): 0:(968.0,1004.0) //注:触摸事件
...
:Sending Key (ACTION_DOWN): 19    // KEYCODE_DPAD_UP //注:导航事件(上下左右)
:Sending Key (ACTION_UP): 19    // KEYCODE_DPAD_UP
...
:Sending Key (ACTION_DOWN): 66    // KEYCODE_ENTER //注:其他事件
:Sending Key (ACTION_UP): 66    // KEYCODE_ENTER
...
:Sending Trackball (ACTION_MOVE): 0:(2.0,2.0) //注:轨迹球事件
...
Sending Flip keyboardOpen=false //注:键盘事件(隐藏显示键盘)
...

注:Monkey的事件种类一般是11种,不同的Android SDK中的Event percentages种类和顺序也不同哦。

CRASH

在Monkey测试过程中可能会出现程序崩溃(CRASH)和程序无响应的情况(ANR),要将测试的log信息获取到,从而解决bug。这里仅以CRASH为例说明。

CRASH即崩溃信息,程序在运行中非正常退出。 不设置忽略crashes,在测试过程中出现CRASH,会中断测试,并显示CRASH信息和seed信息

如下图:
image.png

可直接根据log日志定位bug并修复,也可根据seed值来完成bug的复现。
如:adb shell monkey -p com.feicuiedu.monkeytestdemo -s 1476474162566 -v 100

Monkey的原理

"adb shell monkey"运行机理

实际上是在执行手机中的/sysytem/bin/monkey的脚本文件,其内容如下:

# Script to start "monkey" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/monkey.jar
trap "" HUP
exec app_process $base/bin com.android.commands.monkey.Monkey $*

从系统源码看,其内部是通过/system/bin/app_process来运行/system/framework/monkey.jar。

这里需要注意,JVM中的jar文件是一对class文件的zip包。而在Android中,可执行文件是dex,所以Android里面的jar本质上里面也是dex,直接把eclipse导出的jar包放进去是无法执行的。

其中,app_process会新建一个native进程,初始化虚拟机,从CLASSPATH找到我们定义的Main Class,并把参数传给它。app_process部分启动源码如下:

if (zygote) {
       runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
   } else if (className) {
       runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
 }

adb这里是runtime执行com.android.internal.os.RuntimeInit来启动,位置在:/system/framework/下面。该目录下有很多系统的包,其中有一个/system/framework/monkey.jar为monkey的所在包。

Monkey事件注入机制

Monkey注入系统事件是通过framework层的hidenApi(如:activemanager,inputmanager,windowmanager)获取系统服务。如下:

触摸事件:包括屏幕以及物理键的触摸,滑动,点击事件。
Monkey通过InputManager.getInstance().injectInputEvent(keyEvent, int);构造对应的事件,然后调用该接口执行事件。

Activity事件:是指我们调用Android系统组件的事件。
Monkey通过IActivityManager实例来获取activity的系统服务,从而启动某个activity。

IActivityManager am = ActivityManagerNative.getDefault();
am.startActivity();

Window事件:是指操作Window的事件,例如转屏。
Monkey通过获取IWindowManager实例开启系统窗口服务,并执行窗口事件。

IWindowManager wm = null;
wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
wm..thawRotation();//窗口转屏

Monkey的组织结构

Monkey的核心类是Monkey.java,MonkeyEventSource.java,MonkeyEvent.java。

类名 描述
Monkey 程序的入口,同时也是调度中心,根据参数选择合适的MonkeyEventSource,并适时触发MonkeyEvent。
MonkeyEventSource MonkeyEvent的工厂,是一个接口。它有各种实现,例如随机生成MonkeyEvent,根据配置文件生成MonkeyEvent,根据网络数据生成MonkeyEvent等等。
MonkeyEvent 各种事件的具体实现,是一个抽象类,不同事件有不同实现。在Monkey中各种活动都是事件,除了基本的触摸事件,Activity事件外,事件之间的停顿也是通过一个MonkeyThrottleEvent来实现。这样概念的扩展,将各种活动一视同仁的对待,使设计变得简单。

Monkey中有11种事件,这些事件在MonkeyEventSource中对事件之间的比例进行设置。Monkey事件根据类型比例生成事件队列,循环查找事件。

在MonkeyEventSource中,对于事件来源主要有脚本模式、网络模式(monkeyRunner)和默认模式(随机事件)。
因此,如果我们需要扩展Monkey的功能,只需要增加自己实现的MonkeyEventSource和MonkeyEvent即可。

后续我们一起研究下Monkey的脚本模式~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容