2023年12月14日发(作者:)

Monkey

一.什么是monkey

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

Moneky测试是为了测试软件的稳定性、健壮性的一种有效方法。

二.Monkey的特征

测试的对象仅为应用程序包,有一定局限性

Moneky测试的时间是随机的不能进行自定义

可对monkey test 的对象、事件数量、类型、频率等进行设置。

三.Monkey使用环境的搭建

Monkey环境配置:

首先搭建monkey的运行环境

在Windows下基于SDK

1.下载SDK for Windows 解压:android-sdk-windows 到D:盘根目录

2. 设置sdk下面tools的环境变量(具体参考百度,有详细说明)

/article/

(在下载Sdk前要下载JDK,关于JDK环境变量的配置请参考

/article/) SDK本身的安装是通过sdk manager这个程序下载相关的安装包来进行的,安装好后不会有图标显示在桌面上,因为其本身只是提供相关工具包的使用。

在sdk manager下载过程中,因为谷歌在中国被封杀,而相关工具包的下载都是通过谷歌下载的,所以大家会发现下载速度超慢并且下载经常中断,这里大家可以用迅雷直接在下载地址里下载:

在右下角有个log点击可看到如下: 在Parse XML下即为该该地址文档里所包含的文件,用迅雷将Parse

XML后的地址下载打开,再在里面找到要用的文件名,将Parse XML地址最后面的部分改为文件名成为一个新链接后,将此链接放在迅雷里下载即可。

下载后的文件放到sdk的tools文件夹下并且记得重新打开sdk

manager进行安装:

点击下载好的文件,然后点击左边的install即可。 安装好后即可建立模拟器,可参考:

/article/

在Eclipse里找到AVD manager打开按照如上所述设置(如果遇到显示版本不匹配需要更新等问题,不要去更新,直接在官网下载稳定版本Eclipse IDE for Java EE Developers:

/downloads/

四.Monkey命令使用介绍

usage: monkey [-p ALLOWED_PACKAGE] [-p

ALLOWED_PACKAGE] ...]

[-c MAIN_CATEGORY [-c MAIN_CATEGORY] ...]

[--ignore-crashes] [--ignore-timeouts]

[--ignore-security-exceptions]

[--monitor-native-crashes] [--ignore-native-crashes]

[--kill-process-after-error] [--hprof]

[--pct-touch PERCENT] [--pct-motion PERCENT]

[--pct-trackball PERCENT] [--pct-syskeys PERCENT]

[--pct-nav PERCENT] [--pct-majornav PERCENT]

[--pct-appswitch PERCENT] [--pct-flip PERCENT]

[--pct-anyevent PERCENT]

[--pkg-blacklist-file PACKAGE_BLACKLIST_FILE]

[--pkg-whitelist-file PACKAGE_WHITELIST_FILE]

[--wait-dbg] [--dbg-no-events]

[--setup scriptfile] [-f scriptfile [-f scriptfile] ...]

[--port port]

[-s SEED] [-v [-v] ...]

[--throttle MILLISEC] [--randomize-throttle]

[--profile-wait MILLISEC]

[--device-sleep-time MILLISEC]

[--randomize-script]

[--script-log]

[--bugreport]

COUNT

2、 Monkey命令参数介绍

1) 参数:-p

参数-p用于约束限制,用此参数指定一个或多个包(Package,即APP)。指定包之后,Monkey将只运行系统启动指定的APP。如果不指定包,Monkey将允许系统启动设备中的所有APP。

*指定一个包:adb shell monkey –p 100

说明:为包名,100是事件计数(即让Monkey程序模拟100次随机用户事件)。

*指定多个包:adb shell monkey –p –p

r 100 *不指定包:adb shell monkey 100

说明:monkey随机启动APP并发送100个随机事件。

*要查看设备中所有的包,在CMD窗口中执行以下命令: >adb shell

#cd /data/data

#ls

2) 参数:-c

如果用此指定了一个或几个类别,Monkey将只允许系统启动被这些类别种的某个类别列出的Activity。如果不指定任何类别,Monkey将选择下列类别中列出的Activity:

ER或。要指定多个类别,需要使用多个-c选项,每个-c选项只能用于一个类别。

3) 参数:-v

用于指定反馈信息级别(信息级别就是日志的详细程度),总共分3个级别,分别对应的参数如下所示:

日志级别 Level 0

示例:adb shell monkey –p –v 100

说明:缺省值,仅提供启动提示、测试完成和最终结果等少量信息

日志级别 Level 1

示例:adb shell monkey –p –v –v 100

说明:提供较为详细的日志,包括每个发送到Activity的事件信息

日志级别 Level 2

示例:adb shell monkey –p –v –v –v 100

说明:最详细的日志,包括了测试中选中/未选中的Activity信息

4) 参数:-s

用于指定伪随机生成器的seed值,如果seed相同,则两次Monkey测试所产生的事件序列也相同的。 *示例:

Monkey测试1:adb shell monkey –p –s 10 100

Monkey测试2:adb shell monkey –p –s 10 100

两次测试的效果是相同的,因为模拟的用户序列(每次操作按照一定的先后顺序所组成的一系列操作,即一个序列)是一样的。操作序列虽然是随机生成的,但是只要我们指定了相同的Seed值,就可以保证两次测试产生的随机操作序列是完全相同的,所以这个操作序列伪随机的

5) 参数:--throttle <毫秒>

用于指定用户操作(即事件)间的时延,单位是毫秒;

*示例:adb shell monkey –p –throttle 3000 100

6) 参数 –ignore-crashes

用于指定当应用程序崩溃时(Force & Close错误),Monkey是否停止运行。如果使用此参数,即使应用程序崩溃,Monkey依然会发送事件,直到事件计数完成。

*示例1:adb shell monkey –p –gnore-crashes 1000

测试过程中即使music程序崩溃,Monkey依然会继续发送事件直到事件数目达到1000为止;

示例2:adb shell monkey –p 1000

测试过程中,如果music程序崩溃,Monkey将会停止运行。

7) 参数:--ignore-timeouts 用于指定当应用程序发生ANR(Application No Responding)错误时,Monkey是否停止运行。如果使用此参数,即使应用程序发生ANR错误,Monkey依然会发送事件,直到事件计数完成。

8) 参数:--ignore-security-exceptions

用于指定当应用程序发生许可错误时(如证书许可,网络许可等),Monkey是否停止运行。如果使用此参数,即使应用程序发生许可错误,Monkey依然会发送事件,直到事件计数完成。

9) 参数:--kill-process-after-error

用于指定当应用程序发生错误时,是否停止其运行。如果指定此参数,当应用程序发生错误时,应用程序停止运行并保持当前状态(注意:应用程序仅是静止在发生错误时的状态,系统并不会结束该应用程序的进程)。

10) 参数:--monitor-native-crashes

用于指定是否监视并报告应用程序发生崩溃的本地代码

11) 参数:--pct-{+事件类别} {+事件类别百分比}

用于指定每种类别事件的数目百分比(在Monkey事件序列中,该类事件数目占总事件数目的百分比)

参数:

使用说明:

示例:

①--pct-touch {+百分比} 调整触摸事件的百分比(触摸事件是一个down-up事件,它发生在屏幕的某单一位置)

adb shell monkey –p --pct-touch 10 1000

②--pct-motion {+百分比}

调整动作事件的百分比(动作事件由屏幕上某处的一个down事件、一系列的伪随机事件和up事件组成)

adb shell monkey –p --pct-motion 20 1000

③--pct-trackball {+百分比}

调整轨迹球事件的百分比{轨迹事件由一个或几个随机的移动组成,有时还伴随有点击} adb shell monkey –p --pct-trackball

30 1000j

④--pct-nav {+百分比}

调整“基本”导航事件的百分比(导航事件由来自方向输入设备的up/down/left/right组成)

adb shell monkey –p --pct-nav 40 1000

⑤--pct-majornav {+百分比}

调整“主要”导航事件的百分比(这些导航事件通常引发图形界面中的动作,如:5-way键盘的中间按键、回退按键、菜单按键)

adb shell monkey –p --pct-majormav 50 1000

⑥--pct-syskeys {+百分比}

调整“系统”按键事件的百分比(这些按键通常被保留,由系统使用,如Home,Back,Start Call,End Call及音量控制键)

adb shell monkey –p --pct-syskeys 60 1000

⑦--pct-appswitch {+百分比} 调整启动Activity的百分比。在随机间隔里,Monkey将执行一个startActivity()调用,作为最大程度覆盖包中全部Activity的一种方法

adb shell mokey -p --pct-appswitch 70 1000

⑧--pct-anyevent {+百分比}

调整其它类型事件的百分比。它包罗了所有其它类型的事件,如:按键、其它不常用的的设备按钮、等等

adb shell monkey -p --pct-anyevent 100 1000

*指定多个类型的百分比:adb shell monkey -p

--pct-anyevent 50 --pct-switch 50 1000

12) 参数:--dbg-no-events

设置此选项,Monkey将执行初始启动,进入到一个测试Activity,然后不会再进一步生成事件。为了得到最佳结果,把它与-v、一个或几个包约束、以及一个保持Monkey运行30秒或更长时间的非零值联合起来,从而提供一个环境,可以监视应用程序所调用的包之间的转换。

13) 参数:--hprof

设置此选项,将在Monkey事件序列之前和之后立即生成profiling报告。这将会在/data/misc中生成大文件(~5Mb),所以要小心使用它

14) 参数:--monitor-native-crashes

监视并报告Android系统中本地代码的崩溃事件,如果设置了,系统将停止运行

15) 参数:--wait-dbg

停止执行中的Monkey,直到有调试器和它相连接。

16) 参数:-port 为Monkey开启专用端口。此时只Monkey不会帮你乱点击,而此时你自己就是一只Monkey,在你乱点的时候,Monkey会输出你点击后回馈的信息。如果你打完命令后,模拟器上没有启动你所要启动的包,你需要自己启动,但是你只能启动你-p中指定的那几个包。Ctrl+c中断。

四、 Monkey测试图库实例

1、首先要得到测试apk的包名,如果有APK源码包的话直接将“.apk”后缀改为“.zip”然

后打开包中的可以查看包名,如果没有或者已经安装的点击应用程序,然后查看logcat信息,也能够找到包名,同时在/data/data/目录下面有全部的应用程序的包名,我们要测试的图库的包名为:.

2、设定参数

首先用一个最简单的例子分析

-p参数:表示指定测试的程序

-v参数:表示查看Monkey生成的一些详细的随机的事件名

数字100:表示测试事件数为100

monkey -p -v -v -v 100

结果如下:

# monkey -p -v -v -v 100

monkey -p -v -v -v 100

:Monkey: seed=0 count=100

:AllowPackage:

:IncludeCategory: ER :IncludeCategory:

//各种事件所占的比例

//各数字分别表示 [--pct-touch PERCENT]

[--pct-motion PERCENT]

[--pct-trackball PERCENT]

[--pct-syskeys PERCENT]

[--pct-nav PERCENT]

[--pct-majornav PERCENT]

[--pct-appswitch PERCENT]

[--pct-flip PERCENT]

[--pct-anyevent PERCENT]

// Event percentages // 0: 15.0%

// 1: 10.0% // 2: 15.0%

// 3: 25.0%

// 4: 15.0%

// 5: 2.0%

// 6: 2.0%

// 7: 1.0%

// 8: 15.0%

:Switch:

//表示跳转到里面的Gallery这一个Activity

#Intent;action=;category=

NCHER;launchFlags=0x10000000;component=/.Gallery;end //允许此Intent跳转

// Allowing start of Intent { act=

cat=[

ER] cmp=/.Gallery } in package

Sleeping for 0 milliseconds

//发送一系列动作,如点击按下,点击放开,移动

:SendKey (ACTION_DOWN): 22 // KEYCODE_DPAD_RIGHT

:SendKey (ACTION_UP): 22 // KEYCODE_DPAD_RIGHT

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 23 // KEYCODE_DPAD_CENTER

:SendKey (ACTION_UP): 23 // KEYCODE_DPAD_CENTER

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 59 // KEYCODE_SHIFT_LEFT

:SendKey (ACTION_UP): 59 // KEYCODE_SHIFT_LEFT

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 13 // KEYCODE_6

:SendKey (ACTION_UP): 13 // KEYCODE_6

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 21 // KEYCODE_DPAD_LEFT :SendKey (ACTION_UP): 21 // KEYCODE_DPAD_LEFT

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 23 // KEYCODE_DPAD_CENTER

:SendKey (ACTION_UP): 23 // KEYCODE_DPAD_CENTER

Sleeping for 0 milliseconds

:Sending Pointer ACTION_DOWN x=554.0 y=357.0

:Sending Pointer ACTION_MOVE x=558.0 y=350.0

:Sending Pointer ACTION_MOVE x=558.0 y=350.0

:Sending Pointer ACTION_UP x=558.0 y=350.0

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 3 // KEYCODE_HOME

:SendKey (ACTION_UP): 3 // KEYCODE_HOME

//拒绝此跳转,因为它是跳转的到非它自己的包的Activity,本测试中是指测试它程序所在的包,此跳转是跳出本程序,进入桌面。

// Rejecting start of Intent { act=

cat=[.c

]

cmp=er/er } in package

er

//继续发送动作

Sleeping for 0 milliseconds//-----------------------------用--throttle来设置一个起效的事件发生后时延时

:SendKey (ACTION_DOWN): 20 // KEYCODE_DPAD_DOWN

:SendKey (ACTION_UP): 20 // KEYCODE_DPAD_DOWN

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 82 // KEYCODE_MENU

:SendKey (ACTION_UP): 82 // KEYCODE_MENU

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 48 // KEYCODE_T

:SendKey (ACTION_UP): 48 // KEYCODE_T

Sleeping for 0 milliseconds

:Sending Pointer ACTION_DOWN x=19.0 y=121.0

:Sending Pointer ACTION_MOVE x=20.0 y=123.0

:Sending Pointer ACTION_MOVE x=11.0 y=123.0

:Sending Pointer ACTION_MOVE x=16.0 y=123.0

:Sending Pointer ACTION_UP x=16.0 y=123.0

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 23 // KEYCODE_DPAD_CENTER

:SendKey (ACTION_UP): 23 // KEYCODE_DPAD_CENTER Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 7 // KEYCODE_0

:SendKey (ACTION_UP): 7 // KEYCODE_0

Sleeping for 0 milliseconds

:Sending Pointer ACTION_DOWN x=266.0 y=182.0

:Sending Pointer ACTION_UP x=266.0 y=182.0

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 23 // KEYCODE_DPAD_CENTER

:SendKey (ACTION_UP): 23 // KEYCODE_DPAD_CENTER

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 19 // KEYCODE_DPAD_UP

:SendKey (ACTION_UP): 19 // KEYCODE_DPAD_UP

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 22 // KEYCODE_DPAD_RIGHT

:SendKey (ACTION_UP): 22 // KEYCODE_DPAD_RIGHT

Sleeping for 0 milliseconds

:Sending Pointer ACTION_DOWN x=593.0 y=105.0

:Sending Pointer ACTION_UP x=593.0 y=105.0

Sleeping for 0 milliseconds

:Sending Pointer ACTION_DOWN x=670.0 y=10.0

:Sending Pointer ACTION_UP x=670.0 y=10.0

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 82 // KEYCODE_MENU

:SendKey (ACTION_UP): 82 // KEYCODE_MENU

Sleeping for 0 milliseconds

:Sending Pointer ACTION_DOWN x=534.0 y=101.0

:Sending Pointer ACTION_UP x=534.0 y=101.0

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 63 // KEYCODE_SYM

:SendKey (ACTION_UP): 63 // KEYCODE_SYM

Sleeping for 0 milliseconds

:Sending Pointer ACTION_MOVE x=-3.0 y=0.0

:Sending Pointer ACTION_MOVE x=-2.0 y=-4.0

:Sending Pointer ACTION_MOVE x=-5.0 y=2.0

:Sending Pointer ACTION_MOVE x=-3.0 y=-5.0

:Sending Pointer ACTION_MOVE x=3.0 y=-4.0

:Sending Pointer ACTION_MOVE x=-3.0 y=-4.0//----------------------移动事件 :Sending Pointer ACTION_MOVE x=0.0 y=-2.0

:Sending Pointer ACTION_MOVE x=4.0 y=-1.0

:Sending Pointer ACTION_MOVE x=1.0 y=-5.0

:Sending Pointer ACTION_MOVE x=2.0 y=-5.0

:Sending Pointer ACTION_MOVE x=0.0 y=3.0 :Sending Pointer ACTION_MOVE x=-4.0 y=0.0

:Sending Pointer ACTION_MOVE x=-2.0 y=0.0

:Sending Pointer ACTION_MOVE x=-4.0 y=2.0

:Sending Pointer ACTION_MOVE x=2.0 y=1.0

:Sending Pointer ACTION_MOVE x=-2.0 y=4.0

:Sending Pointer ACTION_MOVE x=-5.0 y=-3.0

:Sending Pointer ACTION_MOVE x=1.0 y=3.0

:Sending Pointer ACTION_MOVE x=3.0 y=4.0

:Sending Pointer ACTION_MOVE x=-2.0 y=4.0

:SendKey (ACTION_DOWN): 19 // KEYCODE_DPAD_UP

:SendKey (ACTION_UP): 19 // KEYCODE_DPAD_UP

Sleeping for 0 milliseconds

:Sending Pointer ACTION_MOVE x=-2.0 y=-2.0

:Sending Pointer ACTION_MOVE x=-2.0 y=-3.0

:Sending Pointer ACTION_MOVE x=-1.0 y=-2.0

:Sending Pointer ACTION_MOVE x=1.0 y=1.0

:Sending Pointer ACTION_MOVE x=-1.0 y=-2.0

:Sending Pointer ACTION_MOVE x=4.0 y=2.0

:Sending Pointer ACTION_MOVE x=3.0 y=4.0

:Sending Pointer ACTION_MOVE x=2.0 y=-4.0

:Sending Pointer ACTION_MOVE x=-5.0 y=-2.0

:Sending Pointer ACTION_MOVE x=-4.0 y=-1.0

:Sending Pointer ACTION_MOVE x=2.0 y=-2.0

:Sending Pointer ACTION_MOVE x=-4.0 y=-2.0

:Sending Pointer ACTION_MOVE x=-2.0 y=-4.0

:Sending Pointer ACTION_MOVE x=0.0 y=1.0

:Sending Pointer ACTION_MOVE x=-3.0 y=0.0

:Sending Pointer ACTION_MOVE x=-3.0 y=-4.0

:Sending Pointer ACTION_MOVE x=2.0 y=1.0

:Sending Pointer ACTION_MOVE x=0.0 y=4.0

:Sending Pointer ACTION_MOVE x=-1.0 y=-4.0

:Sending Pointer ACTION_MOVE x=-4.0 y=1.0

:SendKey (ACTION_DOWN): 20 // KEYCODE_DPAD_DOWN

:SendKey (ACTION_UP): 20 // KEYCODE_DPAD_DOWN

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 21 // KEYCODE_DPAD_LEFT

:SendKey (ACTION_UP): 21 // KEYCODE_DPAD_LEFT

Sleeping for 0 milliseconds

:Sending Pointer ACTION_DOWN x=471.0 y=147.0

:Sending Pointer ACTION_MOVE x=476.0 y=143.0

Events injected: 100

//丢弃的,键=0,指针=0,轨迹球=0,翻转=0.

:Dropped: keys=0 pointers=0 trackballs=0 flips=0 //网络统计经过的时间为16692ms,其中16692ms是用在手机上的,0ms用于无线网络上,没有连接的时间为0ms

## Network stats: elapsed time=16692ms (0ms mobile, 0ms wifi, 16692ms

not connected) //测试完成

// Monkey finished

从例子中可以看出,该程序在这次测试中没有问题,若程序出现问题终端将打印出异常供程序员查找错误。

虽然我们在上面没有出现异常,但是我们通过界面可以看到一些我们平常操作无法出现的一些现象,在上面的测试过程中出现如下图的界面

查看出错信息

# monkey -p -s 14 -v -v -v –port 23

:Monkey: seed=14 count=23

:AllowPackage: ort

:AllowPackage:

:IncludeCategory: ER

:IncludeCategory:

// Selecting main activities from category

ER

// Seeded: 14

// Event percentages:

// 0: 15.0%

// 1: 10.0%

// 2: 15.0%

// 3: 25.0%

// 4: 15.0% // 5: 2.0%

// 6: 2.0%

// 7: 1.0%

// 8: 15.0%

:Switch:

#Intent;action=;category=ER;launchFlags=0x10000000;component=/.Gallery;end

// Allowing start of Intent { act=

cat=[ER]

cmp=/.Gallery } in package

Sleeping for 0 milliseconds

:Sending Pointer ACTION_MOVE x=-2.0 y=-5.0

:Sending Pointer ACTION_MOVE x=1.0 y=-2.0

:Sending Pointer ACTION_MOVE x=0.0 y=3.0

:Sending Pointer ACTION_MOVE x=4.0 y=-3.0

:Sending Pointer ACTION_MOVE x=-3.0 y=4.0

:Sending Pointer ACTION_MOVE x=3.0 y=3.0

:Sending Pointer ACTION_MOVE x=0.0 y=1.0

:Sending Pointer ACTION_MOVE x=3.0 y=1.0

:Sending Pointer ACTION_MOVE x=1.0 y=0.0

:Sending Pointer ACTION_MOVE x=-3.0 y=0.0

:Sending Pointer ACTION_DOWN x=753.0 y=475.0

:Sending Pointer ACTION_UP x=753.0 y=475.0

Sleeping for 0 milliseconds

:SendKey (ACTION_DOWN): 22 // KEYCODE_DPAD_RIGHT //

CRASH: (pid 1132)

// Short Msg: ndexOutOfBoundsException

// Long Msg: ndexOutOfBoundsException

//Build

Label:generic/full_tiger_mb/tiger_mb:2.3.1/GRH78/.20111026.135943:eng/ test-keys //显示当前出错问题的镜像的版本

// Build Changelist: .20111026.135943

// Build Time: 00

// ndexOutOfBoundsException

//at (:313)//指出了出错问题所涉及应用程序源码位置

// at m(:157)

//at Changed(:1277)

//at hEvent(:469) //at

sTouchEvent(:722)

//at Frame(:638)

//at

aceView$dRun(:1363) //at

aceView$(:1118)

//

** Monkey aborted due to error.

Events injected: 14

:Dropped: keys=0 pointers=1 trackballs=0 flips=0

## Network stats: elapsed time=7032ms (0ms mobile, 0ms wifi, 7032ms not

connected)

** System appears to have crashed at event 14 of 23 using seed 14//第14个随机事件时出现问题 我们捕捉到的出错信息有利于开发人员定位问题,测试人员可以从开发板上查看到出错问题的表面现象,两个相互结合有利于bug的修复。