monkey 的使用
monkey的简单操作:
Monkey的智力就是一个三岁小孩的水平,所以,使用起来也是非常简单,当然,也做不了什么复杂的东西
adb shell monkey [options] <event-count> | event-count |
这个是配置monkey的设置, 例如, options是指定启动那个包,不指定将会随机启动所有程序。 event-count是指定随机事件的执行次数。 | 这个是让monkey发送多少次事件 |
实例:
我们验证程序在随机1000次事件中,能不能正常运行下去:
adb shell monkey -p your.package.name -vvv 1000 > monkey1000.txt
这里应当注意:
your.package.name --> 就是你要测试的应用的包名;
1000 --> 就是你要执行的次数;
monkey1000.txt --> 你要将执行结果保存到哪里(要注意的是指明绝对路径)。
-v 为 verbose的缩写,就是详细输出事件等级,这个3个v就是输出等级1至3的所有事件,然后再使用管道命令将输出结果放到一个文本里面方便查看.接下来就是看你的程序能不能在这样的折腾下坚持下去了.
以上截个图看看吧
九个事件及百分比控制
1、九个事件
--pct-touch <percent> 0
调整触摸事件的百分比(触摸事件是一个down-up事件,它发生在屏幕上的某单一位置)(——点击事件,涉及down、up)
--pct-motion <percent> 1
调整动作事件的百分比(动作事件由屏幕上某处的一个down事件、一系列的伪随机事件和一个up事件组成) (——注:move事件,涉及down、up、move三个事件)
--pct-trackball <percent> 2
调整轨迹事件的百分比(轨迹事件由一个或几个随机的移动组成,有时还伴随有点击)--(轨迹球)
--pct-nav <percent> 3
调整“基本”导航事件的百分比(导航事件由来自方向输入设备的up/down/left/right组成)
--pct-majornav <percent> 4
调整“主要”导航事件的百分比(这些导航事件通常引发图形界面中的动作,如:5-way键盘的中间按键、回退按键、菜单按键)
--pct-syskeys <percent> 5
调整“系统”按键事件的百分比(这些按键通常被保留,由系统使用,如Home、Back、Start Call、End Call及音量控制键)
--pct-appswitch <percent> 6
调整启动Activity的百分比。在随机间隔里,Monkey将执行一个startActivity()调用,作为最大程度覆盖包中全部Activity的一种方法。(从一个Activity跳转到另一个Activity)
--pct-flip <percent> 7
调整“键盘翻转”事件的百分比。
--pct-anyevent <percent> 8
调整其它类型事件的百分比。它包罗了所有其它类型的事件,如:按键、其它不常用的设备按钮、等等。
红色的数字对应下面百分比对应的数字。比如下图中0:15.0%,表示分配--pct-touch事件15%。测试100次分配15次测试down-up。
2、百分比控制
如果在monkey参数中不指定上述参数,这些动作都是随机分配的,9个动作其每个动作分配的百分比之和为100%,我们可以通过添加命令选项来控制每个事件的百分比,进而可以将操作限制在一定的范围内。
我们先来看一下不加动作百分比控制,系统默认分配事件百分比的情况
命令:adb shell monkey -p com.android.email -vvv 100 结果:
再看一下指定事件,控制事件百分比之后的情况
命令:adb shell monkey -p com.android.email --pct-anyevent 100 -vvv 100
结果:
说明:--pct-anyevent 100 表明pct-anyevent所代表的事件的百分比为100%。
在monkey测试中常用的命令组合有
1、monkey -p com.yourpackage -v 500 简单的输出测试的信息。
2、monkey -p com.yourpackage -v -v -v 500 以深度为三级输出测试信息。
3、monkey -p com.yourpackage --port 端口号 -v 为测试分配一个专用的端口号,不过这个命令只能输出跳转的信息及有错误时输出信息。
4、monkey -p com.yourpackage -s 数字 -v 500 为随机数的事件序列定一个值,若出现问题下次可以重复同样的系列进行排错。
5、monkey -p com.yourpackage -v --throttle 3000 500 为每一次执行一次有效的事件后休眠3000毫秒。
Moneky Test Log 简单分析:
/*表示跳转到com.android.email里面的Welcome这一个Activity里。*/
/*允许此Intent跳转。*/
/*拒绝次Intent跳转,因为它是跳转到非它自己的包的Activity,本测试中是指写测试它程序所在的包,此跳转是跳出本程序,进入到zhibo8中。*/
/*发送的一些动作,如点击按下,点击放开,移动。 */
/*事件注入次数 100次*/
/*丢弃的,键=0,指针=0,轨迹球=0,轻击=0,翻转=0。*/
/*网络统计经过时间为2556ms,其中0ms是用于在手机上的,2556ms用于无线网络上,没有连接的时间为0ms。*/
/*monkey结束*/
monkey使用时常会遇到的错误:
1 error: device not found
如果你用的是模拟器这说明你的模拟器没有启动成功,需要重启模拟器;如果你的是真机测试,只需将USB重插就行了(但要确保开发者模式-->USB调试已开启)。
然后运行:adb devices 命令行查看是否有设备连接成功。 如下图:
2 error: more than one device and emulator
错误说明是有一个以上的设备和仿真器。这是因为我启用了模拟器,同时我也将我的手机通过USB线连接到了电脑。所以这里存在两个设备。
不信我们可以试试,运行:adb devices 如下图:
这种情况下,需要指定连接某一个设备或者模拟器就行了。
命令行运行:adb -s 1494ab93 shell monkey -p com.android.email -vvv 100
-s是关键字,当有多台设备连接时,使用-s指明你测试要使用的设备。如下图:
monkeyrunner的使用
录制和回放:
1 将以下代码存储为monkey_recorder.py文件,文件名随意。此文件用于启动录制功能。
#!/usr/bin/env monkeyrunner
# Copyright 2010, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from com.android.monkeyrunner import MonkeyRunner as mr
from com.android.monkeyrunner.recorder import MonkeyRecorder as recorder
device = mr.waitForConnection()
recorder.start(device)
2 将以下代码存储为recorder_playback.py文件,文件名随意。此文件用于脚本回放功能。
from com.android.monkeyrunner import MonkeyRunner
CMD_MAP = {
'TOUCH': lambda dev, arg: dev.touch(**arg),
'DRAG': lambda dev, arg: dev.drag(**arg),
'PRESS': lambda dev, arg: dev.press(**arg),
'TYPE': lambda dev, arg: dev.type(**arg),
'WAIT': lambda dev, arg: MonkeyRunner.sleep(**arg)
}
# Process a single file for the specified device.
def process_file(fp, device):
for line in fp:
(cmd, rest) = line.split('|')
try:
# Parse the pydict
rest = eval(rest)
except:
print 'unable to parse options'
continue
if cmd not in CMD_MAP:
print 'unknown command: ' + cmd
continue
CMD_MAP[cmd](device, rest)
def main():
file = sys.argv[1]
device = MonkeyRunner.waitForConnection()
for i in range(1000):
fp = open(file, 'r')
i=i+1
print i
process_file(fp, device)
fp.close();
if __name__ == '__main__':
main()
3 启动安卓模拟器。
4 打开cmd,输入命令monkeyrunner (绝对路径)monkey_recorder.py ,会显示如下界面:
5 录制脚本
⑴、录制功能说明
wait: 用来插入下一次操作的时间间隔,点击后即可设置时间,单位是秒;
Press a Button:用来确定需要点击的按钮,包括menu、home、search,以及对按钮的press、 down、up属性(备注:按钮可以自定义,目前工具提供的只有以上几个按键,其它按键需要时,在脚本中可编辑;
Type Something:用来输入内容到输入框;
Fling:用来进行拖动操作,可以向上、下、左、右,以及操作的范围;
Export Actions:用来导出脚本;
Refresh Display:用来刷新手机界面,估计只有在断开手机后,重新连接时才会用到。
⑵、开始录制,例如:录制一个计算器压力测试脚本
测试机保持在待机界面,工具同步显示待机界面,为保证脚本能更好的运行,一般在每个动作之间建议加一个wait 1秒的动作,点击wait,输入1秒
录制界面如下图:
录制完成点击Export Actions导出脚本,保存为无后缀文件,如下图:
将导出脚本文件后缀改为 .py文件,如下图:
6 脚本回放
首先我们需要更改回放脚本循环次数,打开recorder_playback.py文件,找到以下语句,其中数据可以更改为任意你想要执行的次数,修改成功后保存,现在以1000为例
打开cmd,输入命令monkeyrunner (绝对路径)recorder_playback.py(空格)(绝对路径)test.py,会显示如下界面:
monkeyrunner多设备测试:
接下来用一段典型的monkeyRunner代码讲解!
注意!如果monkeyrunner脚本文件要使用中文,记得格式保存为utf8,不然会ASCII无法支持错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #导入我们需要用到的包和类并且起别名 import sys from com.android.monkeyrunner import MonkeyRunner as mr from com.android.monkeyrunner import MonkeyDevice as md from com.android.monkeyrunner import MonkeyImage as mi
#connect device 连接设备 #第一个参数为等待连接设备时间 #第二个参数为具体连接的设备 device = mr.waitForConnection(1.0,'emulator-5554') if not device: print >> sys.stderr,"fail" sys.exit(1) #定义要启动的Activity componentName='kg.monkey/.MonkeyActivity' #启动特定的Activity device.startActivity(component=componentName) mr.sleep(3.0) #do someting 进行我们的操作 #输入 a s d device.type('asd') #输入回车 device.press('KEYCODE_ENTER') #return keyboard 点击返回用于取消等下看到截图的下方的白条 #device.press('KEYCODE_BACK') #------ #takeSnapshot截图 mr.sleep(3.0) result = device.takeSnapshot()
#save to file 保存到文件 result.writeToFile('takeSnapshot\\result1.png','png'); |
以上代码就是用monkeyrunner 实现操作特定操作以后,并且截图的功能,看上去貌似挺麻烦的…如果你有很多设备要一起测试,你就会发现以上代码是多么爽丫丫的事情.这个脚本的实质就是一个python脚本,懂点,python的朋友,可以利用这个实现非常强悍的功能.
补充一点:如果我们要进行多设备测试怎么办呢?
我们可以打开recorder_playback.py文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | import sys from com.android.monkeyrunner import MonkeyRunner
# The format of the file we are parsing is very carfeully constructed. # Each line corresponds to a single command. The line is split into 2 # parts with a | character. Text to the left of the pipe denotes # which command to run. The text to the right of the pipe is a python # dictionary (it can be evaled into existence) that specifies the # arguments for the command. In most cases, this directly maps to the # keyword argument dictionary that could be passed to the underlying # command.
# Lookup table to map command strings to functions that implement that # command. CMD_MAP = { 'TOUCH': lambda dev, arg: dev.touch(**arg), 'DRAG': lambda dev, arg: dev.drag(**arg), 'PRESS': lambda dev, arg: dev.press(**arg), 'TYPE': lambda dev, arg: dev.type(**arg), 'WAIT': lambda dev, arg: MonkeyRunner.sleep(**arg) }
# Process a single file for the specified device. def process_file(fp, device): for line in fp: (cmd, rest) = line.split('|') try: # Parse the pydict rest = eval(rest) except: print 'unable to parse options' continue
if cmd not in CMD_MAP: print 'unknown command: ' + cmd continue
CMD_MAP[cmd](device, rest)
def main(): file = sys.argv[1] fp = open(file, 'r') #在这里指定你的设备吧 device = MonkeyRunner.waitForConnection()
process_file(fp, device) fp.close();
if __name__ == '__main__': main() |
多设备连接实例
def main():
device1 = MonkeyRunner.waitForConnection(5.0, '1123456789ABCDEF')
if not device1:
print("device1 connection fail")
else:
print("device1 connection success")
device2 = MonkeyRunner.waitForConnection(5.0, '0123456789ABCDEF')
if not device2:
print("device2 connection fail")
else:
print("device2 connection success")
device1.startActivity(component="com.aliyun.wireless.vos.appstore/com.aliyun.wireless.vos.appstore.SlideActivity")
MonkeyRunner.sleep(5)
device2.startActivity(component="com.android.settings/com.android.settings.Settings")
if __name__ == "__main__":
main()
注意:(1)5.0是非常有必要加的,它不是指执行多久,而是多久才执行。