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

Monkey测试参数建议

  • 间隔时间:500毫秒;
  • 种子数:随机;
  • 遇到错误:不停止
  • 执行时长:每机型不小于12小时 或 点击次数:100万次;
  • 机型覆盖建议:覆盖高中低端机型,不同芯片平台,不同分辨率,不同安卓版本;
  • 参考命令: 
    adb shell monkey -p com.package.xxx --throttle 500 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --monitor-native-crashes -v -v -v 1000000>G:\MonkeyTest.log 2>&1 &

Monkey测试方案

  • 单一apk测试: 
    monkey –p <options> -c <options> -s <seed> <限制语句> --throttle <milliseconds> -v 执行次数> G:\MonkeyTest.log

  • 集合apk测试:

    • 黑名单以外的APK: 
      monkey –pkg-blacklist-file /data/local/tmp/blacklist.txt -c <options> -s <seed> <限制语句> --throttle <milliseconds> -v 执行次数>G:\MonkeyTest.log

    • 白名单中APK: 
      monkey –pkg-whitelist-file /data/local/tmp/whitelist.txt -c <options> -s <seed> <限制语句> --throttle <milliseconds> -v 执行次数 > G:\MonkeyTest.log


Monkey测试脚本

Android 的 monkey test 工具提供了 -f scriptfile 参数,可以指定 test 脚本

  • 什么是monkey script 
    Monkey script是按照一定的语法规则编写有序的用户事件流并适用于monkey命令工具的脚本 
    adb shell monkey -f <script file> <运行脚本的次数>

    • 例:adb shell monkey -f /sdcard/monkey.script 10,那么这个脚本里面指定的动作就会被执行10次 
      说明:脚本位置可以是绝对位置,也可以是相对位置(cd进入相应的目录
  • development/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java源码下有一段注释规定了monkey script的基本规则:

    monkey event queue. It takes a script to produce events
    sample script format:
    type= raw events
    count= 10
    speed= 1.0
    start data >>
    captureDispatchPointer(5109520,5109520,0,
    230.75429,458.1814,0.20784314,0.06666667
    ,0,0.0,0.0,65539,0)
    captureDispatchKey(5113146,5113146,0,20,0,0,0,0)
    captureDispatchFlip(true)
    ...
    */
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 脚本的内容示例(源码修正版)

    //header 
    type= raw events 
    count= 10 
    speed= 1.0 
    //line at the end of the header means that below it is the context of script 
    start data >> 
    DispatchPointer(5109520,5109520,0,230.75429,458.1814,0.20784314, 
    0.06666667,0,0.0,0.0,65539,0) 
    DispatchKey(5113146,5113146,0,20,0,0,0,0) 
    DispatchFlip(true) 
    ... 

    说明: 
    1)、前3行是脚本头 
    2)、后3行是脚本内容,每行为一个函数

  • monkey中提供的函数如下:

    1..DispatchPointer(long downTime,  long eventTime, int action, float x, float y, float pressure, float size, int metaState, float xPrecision, float yPrecision, int device, int edgeFlags)
    2..DispatchTrackball(long downTime, long eventTime, int action, float x, float y, float pressure, float size, int metaState, float xPrecision, float yPrecision, int device, int edgeFlags) 轨迹球
    3..DispatchKey(long downTime, long eventTime, int action, int code, int repeat, int metaState, int device, int scancode)
    4..DispatchFlip(boolean keyboardOpen) 实体键盘关闭与打开
    5..DispatchPress(int keyCode)
    6..LaunchActivity(String pkg_name, String cl_name)
    7..UserWait(long sleeptime)
    8..LongPress(int keyCode)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 键盘按下/弹起 
      key [down|up] keycode 
      这个命令模拟一次键盘输入。 
      keycode参数值详见KeyEvent类的KEYCODE列表。这个参数的格式很灵活,例如模拟菜单按钮可以使用82(菜单按钮的键值),也可以使用 KEYCODE_MENU(键值的名称,必须严格都是大写字母),还可以使用menu(Monkey程序会自动添加KEYCODE部分,此时并不区分大小 写)。 
      注意一次完整的敲击(press)操作是一个按下(key down)和弹起(key up)的组合
    • 触摸按下/弹起/移动 
      touch [down|up|move] x y 
      This command injects a MotionEvent into the input system that simulates a user touching the touchscreen (or a pointer event). x and y specify coordinates on the display (0 0 being the upper left) for the touch event to happen. Just like key events, touch events at a single location require both a down and an up. To simulate dragging, send a “touch down”, then a series of “touch move” events (to simulate the drag), followed by a “touch up” at the final location.
    • 滚动轨迹球 
      trackball dx dy 
      This command injects a MotionEvent into the input system that simulates a user using the trackball. dx and dy indicates the amount of change in the trackball location (as opposed to exact coordinates that the touch events use)
    • 打开/关闭实体键盘 
      flip [open|close] 
      模拟一次实体键盘的打开/关闭。 
      在没有实体键盘的手机上此命令无效。
    • 唤醒设备(点亮屏幕) 
      wake 
      这个命令将唤醒设备,并允许用户输入。 
      如果设备键盘已锁,这个命令并不能解锁键盘
    • 屏幕点击 
      tap x y 
      这个命令模拟一次屏幕点击。 
      这个命令就是touch down和touch up命令的一次组合。
    • 敲击键盘 
      press keycode 
      这个命令模拟一次键盘敲击。 
      这个命令就是key down和key up命令的一次组合。
    • 键入字符串 
      type string 
      这个命令模拟键入一个字符串 
      该命令会完全模拟每一个字符的键盘事件 
      列出环境变量
    • listvar 
      该命令将列出Monkey的所有环境变量。 
      返回值为空格分隔的字符串。
    • 获取环境变量值 
      getvar varname 
      该命令用于获取指定的环境变量的值。 
      通过listvar命令获取支持的环境变量列表。
    • 退出Monkey 
      quit 
      完全退出Monkey 
      Monkey不再接受新的连接。
    • 结束当前会话 
      done 
      结束当前会话。 
      Monkey还可以接受新的连接。
    • 休眠 
      sleep ms 
      使Monkey进入休眠一段时间,参数为整数,单位毫秒
    • 注释 
      # 
      以#开头的语句会被Monkey当做注释。发送这样的命令Monkey不会返回错误也不会返回OK。
  • 常用函数介绍 
    以下列表提炼于源码MonkeySourceScript.java 
    DispatchKey(downTime,eventTime,action,code,repeat,metaState,device,scancode) 
    @param long downTime //键最初被按下的时间 
    @param long eventTime //事件发生的时间 
    @param int action //(ACTION_DOWN=0,ACTION_UP=1,ACTION_MULTIPLE=2) 
    @param int code //键值,比如KEYCODE_DPAD_DOWN(20) 
    @param int repeat // 
    @param int metaState //当前按下的meta键的标识 
    @param int device //事件发生的设备id 
    @param int scancode // 
    DispatchPointer(downTime, eventTime,action, x, y, pressure, size, metaState, xPrecision,yPrecision,device, edgeFlags) 
    @param long downTime //键最初被按下的时间 
    @param long eventTime //事件发生的时间 
    @param int action //(ACTION_DOWN=0,ACTION_MOVE=1,ACTION_UP=2,ACTION_CANCEL=3) 
    @param float x //x坐标 
    @param float y //y坐标 
    @param float pressure //当前事件的压力,范围0-1 
    @param float size //触摸的近似值,范围0-1 
    @param int metaState //当前按下的meta键的标识 
    @param float xPrecision //x坐标精确值 
    @param float yPrecision //y坐标精确值 
    @param int device //事件来源,范围0-x,0表示不来自物理设备 
    @param int sedgeFlags // 
    DispatchTrackball(downTime, eventTime,action, x, y, pressure, size, metaState, xPrecision,yPrecision,device, edgeFlags) 
    Tap(x,y,duration); 
    DispatchPress(String key_name) 
    DispatchFlip(boolean keyboardOpen) 
    UserWait(long sleeptime) 
    LaunchActivity(String pkg_name, String cl_name,long alarmTime) 
    UserWait(long sleeptime) 
    LongPress()

示例:

  • Start Script 
    type = user 
    count = 49 
    speed = 1.0 
    start data >> 
    LaunchActivity(com.android.browser,com.android.browser.BrowserActivity) 
    UserWait(5000)
     
    #back to home 
    captureDispatchPointer(5109520,5109520,0,1150,330,0,0,0,0,0,0,0); 
    captureDispatchPointer(5109521,5109521,1,1150,330,0,0,0,0,0,0,0); 
    UserWait(3000)
     
    #close browser 
    captureDispatchPointer(5109520,5109520,0,205,31,0,0,0,0,0,0,0); 
    captureDispatchPointer(5109521,5109521,1,205,31,0,0,0,0,0,0,0); 
    UserWait(2000)
     
    以上是一个示例脚本。 
    具体的操作步骤为: 
    1. 将上述脚本复制到script.txt中
    2. 将script.txt放到sd卡根目录
    3. adb shell monkey –v –v –v –f /sdcard/script.txt –throttle 1500 100 > monkey.txt 
      脚本会按照script.txt发送的指令序列每隔1.5s执行一个指令,执行100遍,并将log存在monkey.txt文件中

Monkey测试结果分析

  • Android平台应用程序可能产生以下四种Crash:

    • App层: 
      1、Force Close Crash 
      2、ANR Crash
    • Native层: 
      3、Tombstone Crash(Native Crash)
    • Kernel层: 
      4、Kernel Panic
  • 主要Monkey日志

    • anr目录:从手机/data/anr导出的日志,保存发生anr crash 时的相关信息;
    • dontpanic目录:从手机/data/dontpanic/导出的日志,保存发生Kernel Panic时的相关信息;
    • Tombstone目录:从手机/data/tombstones/导出的日志,保存发生Tombstone Crash时的错误信息;
    • dropbox目录:从手机/data/system/dropbox/导出的日志,经过dropbox服务截取的部分tombstones错误信息;
    • BugReportLog.log:通过adb shell bugreport命令提取的系统各种信息;
    • MonkeyTest.Log:保存Monkey测试过程、应用层错误信息,发生Native Crash时,在此文件也会有记录;
  • 一般的测试结果分析: 
    Monkey测试出现错误后,一般的差错步骤为以下几步:

    • 找到是monkey里面的哪个地方出错
    • 查看Monkey里面出错前的一些事件动作,并手动执行该动作
    • 若以上步骤还不能找出,可以使用之前执行的monkey命令再执行一遍,注意seed值要一样
    • 在MonkeyTest.Log日志文件搜索关键词“Fatal”、“Crash”、“ANR”定位到发生Crash的详细堆栈信息,或分析发生Crash前后的日志事件;
    • 检查dropbox目录下是否有相关crash日志信息,主要关注是否有以下4类crash错误信息: 
      data_app_wtfdata_app_anrdata_app_crashsystem_server_watchdog
    • 检查tombstone目录是否有生成日志,有的话说明发生过native crash
    • 通过anr目录中的日志文件或BugReport.log日志文件,进一步分析问题原因;

Monkey测试的延伸

monkey工具不能实现指定模块测试,以下记录两种实现指定模块测试的方法

方法1: 
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice 
from random import randint 
print("get device") 
device = MonkeyRunner.waitForConnection() 
package = 'com.swl.a1vod' 
activity = 'org.coolx.videoframework.vod.VodDetailsActivity' 
runComponent = package + '/' + activity 
device.startActivity(component=runComponent)

#use commands like device.touch and device.drag to simulate a navigation and open my activity 
#with your activity opened start your monkey test 
print("start monkey test") 
for i in range(1, 1000): 
#here i go emulate only simple touchs, but i can emulate swiper keyevents and more... :D 
device.touch(randint(0, 1000), randint(0, 800), 'DOWN_AND_UP') 
print("end monkey test")

#执行monkeyrunner G:\script\monkeytest.py

方法2:

<activity android:name="MonkeyActivity"> 
<intent-filter> 
<action android:name="android.intent.action.MAIN" /> 
<category android:name="android.intent.category.MONKEY" /> 
</intent-filter> 
</activity>

adb shell monkey -p my.package -c android.intent.category.MONKEY -v 500


更多参考资料 
1、Monkey 
2、android 常见死机问题–log分析 
3、分析bugreport 
4、如何分析解决Android ANR 
5、Android Tombstone Crash的log分析和定位 
6、Android中对Log日志文件的分析 
7、Watchdog kills system service in system_server 
8、android ANR异常及其解决方式

monkey测试===Android测试工具Monkey用法简介(转载)的更多相关文章

  1. Apache自带压力测试工具ab用法简介

    ab命令原理 ab命令会创建很多的并发访问线程,模拟多个访问者同时对某一URL进行访问.它的测试目标是基于URL的,因此,既可以用来测试Apache的负载压力,也可以测试nginx.lighthttp ...

  2. Android自动化测试工具——monkey简介及入门

    记得第二家单位的安卓开发在上线前都用monkey压几个小时,确实也能发现些问题,崩溃率低了些,没测过的确实可以压一压 搜了下资料,monkey确实很简单,发现问题自己搜下是什么问题,别一发现什么就跑去 ...

  3. C++ Json工具--Jsoncpp用法简介

    文章目录 Json简介 用法简介 数据类型 C++代码示例 代码执行输出结果 JSON在线解析及格式化验证 - JSON.cn Json简介 JSON(JavaScript Object Notati ...

  4. Android中Toast的用法简介

    转自:http://www.cnblogs.com/GnagWang/archive/2010/11/26/1888762.html Toast是Android中用来显示显示信息的一种机制,和Dial ...

  5. Android——ViewGroup的一个用法实例(转载)

    找了很久,终于找到了. <?xml version="1.0" encoding="UTF-8" ?> <merge xmlns:androi ...

  6. android:ellipsize省略文字用法(转载)

    转自:http://zhangkun716717-126-com.iteye.com/blog/864989 TextView及其子类,当字符内容太长显示不下时可以省略号代替未显示的字符:省略号可以在 ...

  7. Postman用法简介

    转自:http://blog.csdn.net/flowerspring/article/details/52774399 Postman用法简介 转载 2016年10月10日 09:04:10 10 ...

  8. Android压力测试工具——Monkey

    Android压力测试工具——Monkey Monkey是运行在模拟器上和真机设备上的一段程序,它会产生用户事件的一系列伪随机流,比如点击.触摸.手势,还有很多系统级别的事件.Monkey通常是用来做 ...

  9. 【Android】自动测试工具 Monkey

    前言: 最近开始研究Android自动化测试方法,对其中的一些工具.方法和框架做了一些简单的整理,其中包括android测试框架.CTS.Monkey.Monkeyrunner.benchmark.其 ...

随机推荐

  1. SpringBoot2.0(五) CORS跨域

    部分跨域 @CrossOrigin注解支持类级别,方法级别添加.可以在controller类或者方法上添加,支持部分接口跨域.在两者上都添加时,方法级别的覆盖类级别的. 属性 说明 origins 允 ...

  2. java read读取方法 之 指定读取大小,根据返回值判断是否读取所有的内容 -1表示读取完毕

    当读取的内容小于指定的长度时候 字符数组里面会出现一部分字符是上一次遗留下来的情况

  3. Elasticsearch 插件head和kibana

    本次安装在win7下,linux操作差不多. Elasticsearch的版本是6.5.1 一.前置条件 1.安装nodejs,如果已经安装了,检查一下版本,最好大于6以上,不然后面会失败,官网上已经 ...

  4. 【刷题】BZOJ 3527 [Zjoi2014]力

    Description 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. Input 第一行一个整数n. 接下来n行每行输入一个数,第i行表示qi. n≤100000,0<qi ...

  5. 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告

    P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...

  6. [APIO2017]商旅

    link 这题卡我精度,调了一晚上才调对,因为没有想到图还可以不连通 其实可以预处理出好多东西,距离($dis(u,v)$),买卖物品(从$u$到$v$买卖物品的最大利润,例($max{S_{u,i} ...

  7. 【P2602】【ZJOI2012】数字计数

    传送门 Description 给定两个正整数\(a\)和\(b\),求在\([a,b]\)中的所有整数中,每个数码(\(digit\))各出现了多少次. Input 两个正整数\(a,b\) Out ...

  8. Linux之socket套接字编程20160704

    介绍套接字之前,我们先看一下传输层的协议TCP与UDP: TCP协议与UDP协议的区别 首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UD ...

  9. CCPC-Winter Camp div2 day5

    DIV2 有部分div1的题会写 div1的大佬真的太强了 向他们学习 (好像和zqc大佬说过话了hhh,zqc大佬真的是一个超有意思的人啊,羡慕有妹子队友的zqc大佬) A: 你有一棵树,你想把它画 ...

  10. bzoj 4900 [CTSC2017]密钥 模拟+乱搞

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4900 #include<cstring> #include<cmath&g ...