Monkey

Monkey:Android SDK自带的一个命令行工具,使用adb来运行它,向系统发送伪随机的用户事件流,如按键、触屏、输入等;实现对正在开发的应用程序进行压力测试,伴随着日志输出。实际上该工具只能做程序做一些压力测试,由于测试事件和数据都是随机的,不能自定义,所以有很大的局限性。

MonkeyRunner:Android SDK提供的测试工具,位于tools目录下,比Monkey强大,可以编写脚本来自定义数据,事件;但是脚本是采用python语言编写的,其实就是对python进行了封装,对测试人员要求较高。

Instrumentation:这个是Google早期提供的测试自动化测试工具类,可以看成是Android的一个组件,可以模拟用户众多事件,通常用来单元测试,对测试人员要求较高,需要了解Android的api。

UiAutomator:Android提供的自动化测试框架,也是前两年最佳的UI测试框架,基本上支持所有的用户事件,可以抓取APP页面控件属性,测试代码结构简单,编写容易,能跨APP测试,但是要求设备在Android4.1以上,不支持Hybird APP,WebApp。

Appium:这应该是最近很火的一个测试框架,支持Native APP,Hybird APP,Web APP;可以跨平台在Windows,Mac,Linux使用,支持Android,ios;支持java,js,php,Python等语言编写测试脚本。

Monkey命令介绍

我们在cmd中先进入adb所在目录,然后输入命令 adb shell monkey -help 可以查看到monkey相关的命令


-p 用于约束限制,用此参数指定一个包,指定包后Monkey将被允许启动指定应用;如果不指定包,  Monkey将被允许启动设备中的所有应用(主Activity有android.intent.category.LAUNCHER 或android.intent.category.MONKEY类别 )。比如 adb shell monkey -p xxx.xxx.xxx 1  ; xxx.xxx.xxx 表示应用包名,1 表示monkey模拟用户随机事件参数,最低1,这样就能把应用启动起来

-v 用于指定反馈信息级别,也就是日志的详细程度,分三个;-v 默认值,仅提供启动提示,操作结果等少量信息 比如adb shell monkey -p  xxx.xxx.xxx -v 1 ;-v -v 提供比较详细信息,比如启动的每个activity信息 ,比如adb shell monkey -p xxx.xxx.xxx -v -v 1 ;-v -v -v 提供最详细的信息 ,比如adb shell monkey -p xxx.xxx.xxx -v -v -v 1 

-s 伪随机数生成器的种子值,如果我们两次monkey测试事件使用相同的种子值,会产生相同的事件序列;如果不指定种子值,系统会产生一个随机值。种子值对我们复现bug很重要。使用如下adb shell monkey -p xxx.xxx.xxx -s 11111 10

--ignore-crashes 忽略异常崩溃,如果不指定,那么在monkey测试的时候,应用发生崩溃时就会停止运行;如果加上了这个参数,monkey就会运行到指定事件数才停止。比如adb shell monkey -p xxx.xxx.xxx -v -v -v  --ignore-crashes 10 

--ignore-timeouts 忽略ANR,情况与4类似,当发送ANR时候,让monkey继续运行。比如adb shell monkey -p xxx.xxx.xxx -v -v -v  --ignore-timeouts 10

--ignore-native-crashes 忽略native层代码的崩溃,情况与4类似,比如adb shell monkey -p xxx.xxx.xxx -v -v -v  --ignore-native-crashes 10

--ignore-security-exceptions 忽略一些许可错误,比如证书许可,网络许可,adb shell monkey -p xxx.xxx.xxx -v -v -v  --ignore-security-exceptions 10

--monitor-native-crashes 是否监视并报告native层发送的崩溃代码,adb shell monkey -p xxx.xxx.xxx -v -v -v  --monitor-native-crashes 10

--kill-procress-after-error 用于在发送错误后杀死进程

--hprof  设置后,在Monkey事件序列之前和之后立即生产分析报告,保存于data/mic目录,不过将会生成大量几兆文件,谨慎使用

--throttle 设置每个事件结束后延迟多少时间再继续下一个事件,降低cpu压力;如果不设置,事件与事件之间将不会延迟,事件将会尽快生成;一般设置300ms,因为人最快300ms左右一个动作,比如 adb shell monkey -p xxx.xxx.xxx -v -v -v  --throttle 300 10

--pct-touch 设置触摸事件的百分比,即手指对屏幕进行点击抬起(down-up)的动作;不做设置情况下系统将随机分配各种事件的百分比。比如adb shell monkey -p xxx.xxxx.xxx --pct-touch 50 -v -v 100 ,这就表示100次事件里有50%事件是触摸事件

--pct-motion 设置运动事件百分比,这种事件类型是由屏幕上某处的一个down事件-一系列伪随机的移动事件-一个up事件,即点击屏幕,然后直线运动,最后抬起这种运动。

--pct-trackball 设置轨迹球事件百分比,这种事件类型是一个或者多个随机移动,包含点击事件;这里可以是曲线运动

--pct-syskeys 设置系统按键事件百分比,比如home键,音量键,返回键,拨打电话等

--pct-nav 设置基本的导航按键事件百分比,比如输入设备上的上下左右四个方向键

--pct-appswitch 设置activity跳转事件的百分比

--ptc-anyevent 设置其它事件百分比

--ptc-majornav 设置主导航事件的百分比

保存dos窗口打印的monkey信息,在monkey命令后面补上输出地址,如adb shell monkey -p xxx.xxxx.xxx  -v -v 100 > D:\monkey.txt;这样monkey测试结束后,所有打印的信息都会输出到这个文件里

通过adb bugreport 命令可以获取整个android系统在运行过程中所有app的内存使用情况,cpu使用情况,activity运行信息等,包括出现异常等信息。使用方法 adb bugreport > bugreport.txt ;这样在当前目录就会产生一个txt文件和一个压缩包,具体信息可在压缩包查看,txt文件只会记录压缩包的生成过程信息

-f 加载monkey脚本文件进行测试,比如 adb shell monkey -f sdcard/monkey.txt -v -v 500

Monkey使用

1.进入adb目录

2.通过adb install apk名字

3.输入adb shell monkey -p xxx.xxxx.xxx  -s 123123 --throttle 300 -v -v 20 > d:\monkey.txt,这里指定了seed值,每个事件之间休息300ms,执行了20个事件,然后将日志信息保存在了monkey.txt文件中

4.打开文件,查看信息如下:

Monkey: seed=123123 count=20 //seed值是指定的123123,方便出现bug后再复现 事件次数是20

:AllowPackage: com.android.mangodialog // 应用包名

:IncludeCategory: android.intent.category.LAUNCHER //启动的主activity的类别,两种只要有一种就行

:IncludeCategory: android.intent.category.MONKEY

// Selecting main activities from category android.intent.category.LAUNCHER

//   + Using main activity com.android.mangodialog.MainActivity (from package com.android.mangodialog) //该应用符合这种类别的activity

// Selecting main activities from category android.intent.category.MONKEY

// Seeded: 123123

// 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%  

//   5: -0.0%  

//   6: 25.0%  //可通过--pct-nav 参数设置的事件的百分比

//   7: 15.0%  //可通过--pct-majornav 参数设置的事件的百分比

//   8: 2.0%   //可通过--pct-syskeys 参数设置的事件的百分比 常用

//   9: 2.0%   //可通过--pct-appswitch 参数设置的事件的百分比 常用

//   10: 1.0%  //可通过--pct-flip 参数设置的事件的百分比

//   11: 13.0% //可通过--pct-anyevent 参数设置的事件的百分比 

//启动的activity

:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.mangodialog/.MainActivity;end

    // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.android.mangodialog/.MainActivity } in package com.android.mangodialog

Sleeping for 300 milliseconds //设置的事件之间间隔300ms 下面就是执行点击事件

:Sending Key (ACTION_DOWN): 82    // KEYCODE_MENU

:Sending Key (ACTION_UP): 82    // KEYCODE_MENU

Sleeping for 300 milliseconds

:Sending Key (ACTION_DOWN): 23    // KEYCODE_DPAD_CENTER

:Sending Key (ACTION_UP): 23    // KEYCODE_DPAD_CENTER

Sleeping for 300 milliseconds

    // Allowing start of Intent { cmp=com.android.mangodialog/.MainActivity2 } in package com.android.mangodialog

:Sending Key (ACTION_DOWN): 22    // KEYCODE_DPAD_RIGHT

:Sending Key (ACTION_UP): 22    // KEYCODE_DPAD_RIGHT

Sleeping for 300 milliseconds

:Sending Key (ACTION_DOWN): 21    // KEYCODE_DPAD_LEFT

:Sending Key (ACTION_UP): 21    // KEYCODE_DPAD_LEFT

Sleeping for 300 milliseconds

:Sending Touch (ACTION_DOWN): 0:(1017.0,280.0)

:Sending Touch (ACTION_UP): 0:(1021.8751,281.12732)

Sleeping for 300 milliseconds

:Sending Touch (ACTION_DOWN): 0:(1005.0,1599.0)

:Sending Touch (ACTION_UP): 0:(994.4962,1589.7715)

Sleeping for 300 milliseconds

:Sending Key (ACTION_DOWN): 2    // KEYCODE_SOFT_RIGHT

:Sending Key (ACTION_UP): 2    // KEYCODE_SOFT_RIGHT

Sleeping for 300 milliseconds

:Sending Key (ACTION_DOWN): 20    // KEYCODE_DPAD_DOWN

:Sending Key (ACTION_UP): 20    // KEYCODE_DPAD_DOWN

Sleeping for 300 milliseconds

:Sending Key (ACTION_DOWN): 22    // KEYCODE_DPAD_RIGHT

:Sending Key (ACTION_UP): 22    // KEYCODE_DPAD_RIGHT

Sleeping for 300 milliseconds //轨迹球运动

:Sending Trackball (ACTION_MOVE): 0:(4.0,-5.0)//手机屏幕上的坐标

Events injected: 20 //monkey共执行了20次事件

:Sending rotation degree=0, persist=false

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

//测试过程中的网络状态,花费了3064ms连接,既没有连接上手机网络,也没有连接上wifi

## Network stats: elapsed time=3064ms (0ms mobile, 0ms wifi, 3064ms not connected) 

// Monkey finished //monkey测试结束

5.平时会使用比较复杂的参数去测试,如下

adb shell monkey -v -v -v -s 123123 --throttle 300 --pct-touch 40 --pct-motion 25 --pct-appswitch 25 --pct-syskeys 10 --pct-majornav 0 --pct-nav 0 --pct-trackball 0 --ignore-crashes --ignore-timeouts --ignore-native-crashes -p xxx.xxx.xxx 100000 > d:\monkey.txt

具体什么意思就不再一一解释了。

6.其实我们比较关注的是app在使用过程中出现的错误信息,像上面我们选择忽略掉集中错误情况,这样当monkey执行结束后,相关的信息会被写入到monkey文件中,但是错误信息比如crash,anr等信息会打印在dos窗口,这些错误信息会明确的指出哪里发生的错误;如果需要复现,我们可以把忽略参数去掉,然后通过相同的seed值再次进行monkey测试,直到发生错误跳出monkey测试,我们再查看,如下

public class MainActivity2 extends AppCompatActivity {

    @Override

    protected void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.act_main2);

        float s = 1/0;

    }

}

我这第二个activity的oncreate方法中写这个会报错的代码,然后在第一个activity的一个按钮中进行跳转进入这个activity,接下来进行monkey测试来复现这个bug

adb shell monkey -p xxx.xxx.xxx -s 123456 -v -v 2000  > d:\monkey.txt

我们看这个文件

:Sending Trackball (ACTION_MOVE): 0:(4.0,-3.0)

:Sending Trackball (ACTION_MOVE): 0:(-2.0,1.0)

:Sending Trackball (ACTION_DOWN): 0:(0.0,0.0)

:Sending Trackball (ACTION_UP): 0:(0.0,0.0)

Sleeping for 300 milliseconds

    // Allowing start of Intent { cmp=com.android.mangodialog/.MainActivity2 } in package com.android.mangodialog

** Monkey aborted due to error.

Events injected: 190

这里可以看到是当打开MainActivity2的时候monkey发生错误退出,只执行了190个事件。至于错误信息打印在了dos窗口。

这里我们也可以通过adb bugreport命令将手机运行日志导出来查看,这里面的信息更详细,包括出错信息。


Monkey脚本

monkeyscript是monkey的脚本语言,能够被monkey识别的命令集合,可以实现一些固定的重复性动作。Monkey可以通过命令加载脚本来进行测试,简单方便。

脚本格式如下:

type= raw events

count= 1

speed= 1.0   

start data >>   

LaunchActivity(pkg_name, cl_name)  

第一句到第三局就使用默认值,不需要改,其实这里设置是无效的,最终会采用命令行里的值;

start data >> 表示开始执行下面所有的命令行

LaunchActivity就是一个启动应用的命令

脚本命令

LaunchActivity(pkg_name, cl_name) 打开应用,第一个参数是包名,第二个是启动的activity名

DispatchPress(keyName) 按下物理按键,例如home键,back键;参数是按键值 ,按键值可查看keycode

Tap(x, y) 点击屏幕,参数是点击坐标

Drag(xStart, yStart, xEnd, yEnd) 滑动屏幕,坐标是从哪一点滑到哪一点

LongPress() 长按2s

ProfileWait 等待5s

PressAndHold(x, y, pressDuration) 模拟长按 

PinchZoom(x1Start, y1Start, x1End, y1End, x2Start, y2Start, x2End, y2End, stepCount) 模拟缩放

DispatchString(input) 输入字符串

RunCmd(cmd) 执行shell命令,比如截图 screencap -p /data/local/tmp/tmp.png

RotateScreen(rotationDegree, persist) 选择屏幕,第一个参数是旋转角度,第二个是旋转后是否停在当前位置

DispatchFlip(true/false) 打开或者关闭软键盘

UserWait(sleepTime) 睡眠指定时间

DeviceWakeUp() 唤醒屏幕

DispatchPointer(downtime,eventTime,action,x,yxpressure,size,metastate,xPrecision,yPrecision,device,edgeFlags) 向指定位置发送单个手势

更多方法可查看Monkey源码

https://github.com/gb112211/Android-Platform-Development/tree/master/cmds/monkey/src/com/android/commands/monkey

现在来写一个脚本:

type= raw events

count= 1

speed= 1.0   

start data >>   

LaunchActivity(com.android.mangodialog,com.android.mangodialog.MainActivity);

UserWait(1000);

Tab(500,300);

DispatchPress(KEYCODE_ENTER)

UserWait(1000);

DispatchPress(KEYCODE_BACK);

UserWait(1000);

RunCmd(screencap -p /sdcard/tmp.png);

UserWait(1000);

Drag(0, 0, 500, 500);

DispatchPress(KEYCODE_ENTER)

UserWait(1000);

DispatchString(www.baidu.com);

UserWait(1000);

DispatchPress(KEYCODE_BACK);

UserWait(1000);

然后通过adb push d:\monkey.txt sdcard/monkey.txt 将文件推送到手机sd卡上,然后通过

adb shell monkey -f sdcard/monkey.txt -v -v 1 执行脚本文件

---------------------


原文:https://blog.csdn.net/qq_30993595/article/details/80748559

https://blog.csdn.net/zjnuwsf/article/details/52669764

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