欢迎大家来到IT世界,在知识的湖畔探索吧!
- 简介
- Monkey是Android SDK提供的一个命令行工具,可以运行在模拟器里或实际设备中简单方便的发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试。Monkey测试是一种为了测试软件的稳定性、健壮性的快速有效的方法。主要是为了测试app是否存在无响应和崩溃的情况Monkey程序由Android系统自带,使用Java语言编写。 在Android操作系统中的存放路径是: /system/framework/monkey.jar Monkey.jar程序是由一个名为“monkey”的Shell脚本来启动执行,shell脚本在Android文件系统中的存放路径是:/system/bin/monkey 运行原理:
- monkey测试原理:
- Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流
(如 按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试。Monkey测试是一种为了测试软件的稳定性、健壮性的快速有效的方法。
- Monkey启动方式:
- 通过PC机CMD窗口中执行: adb shell monkey {+命令参数} 在PC上 adb shell 进入Android系统,通过执行 :monkey {+命令参数}
- Monkey 架构
- Adb 后台守护进程:
- Monkey测试 环境(模拟器、真机 )
- Monkey主要是借助adb命令来让PC与Android设备连接,adb是一种Android调试工具,在PC上配置好环境即可使用
- 1) 安装并配置JDK环境和环境变量
- 2) 安装并照配置Android SDK环境和环境变量
- 3) 将模拟器或手机连接到PC
- 4) 因测试多针对一个特定的APP包,所以需要知道需要测试包的包名
- Monkey的使用(先连接真机或模拟器)
1、基本格式:
- 通过PC机CMD窗口执行: adb shell monkey {+命令参数}
- 最基本测试的命令:adb shell monkey <event-count>
- 这样直接在Terminal中输入,就会像设备上发送指定的事件数的事件。
- 但是在Terminal中不会有任何输出,如果需要有输出,可以加上-v参数。-v表示输出的Log级别,-v最低,
-v -v -v最高。
- adb shell monkey -v <event-count>
2、指定APP
- 上面的命令表示向设备输入100个随机事件,如果正确输出,可以在设备上看到各种点击效果一闪而过。但是这种随机的输入其实也是没什么作用的,通常我们会需要指定在某一个App内做随机事件。那么,可以
再增加-p参数,完整命令如下
- 格式:adb shell monkey -p com.mipay.wallet -v <event-count>
3、一个完整的monkey语句:
adb shell monkey -p your.package.name –pct-touch 30 –ignore-crashes –ignore-timeouts–throttle 250 -s 2 -v -v -v
触摸事件占30%,忽略crash和超时,每个事件间隔250ms,输出最详细日志,执行500万次
4、查看需要测试的包名
如果有root权限,可以进入/data/data/下使用ls/ls-a查看(或ll)
如果无root权限,可以使用:pm list packages查看
5、monkey执行的时间计算
需要控制monkey执行的时间,可以通过设置执行时长/事件发送延时,计算出需要执行的次数。
如:想要monkey运行24小时,每100毫秒发送一个事件。24*60*60*1000/100=(次)
monkey -p * –ignore-crashes –ignore-timeouts –throttle 100
表示:此次monkey将会运行24小时
例:运行3天,如何设置参数:
先运行100次时间大概是多少?运行1000次时间又是多少?然后可以根据时间差值,来计算3天大概需要运行多少次(经验)
- Monkey的命令参数详细说明
1、monkey的命令参数分为:
基础参数:-v 、-s 、-p 、–throttle [ˈθrɒtl]】等
调试选项:–ignore-crashes等
事件类型:–pct-touch等
Monkey中更多参数含义可以通过-h查看帮助文档。
Adb shell monkey -h
- 基础参数
- monkey 100
表示:在设备上,针对整个系统发送100个伪随机事件。
- -v参数
用于指定反馈信息级别(信息级别就是日志的详细程度)总共分为3级,默认为-v(对应:level0)
-v:只提供启动提示、测试完成提示和最终结果等少量信息。
-v -v:较为详细的日志,包括每个发送到activity的时间信息。
-v –v -v:最详细的日志,包括测试中选中/未选中的activity信息。
.adb shell monkey –v 100
.adb shell monkey –v –v 100
.adb shell monkey –v –v –v 100
示例:
- Level 0 : adb shell monkey -p com.android.calculator2 -v 100
// 缺省值,仅提供启动提示、测试完成和最终结果等少量信息
- Level 1 : adb shell monkey -p com.android.calculator2 -v -v 100
// 提供较为详细的日志,包括每个发送到Activity的事件信息
- Level 2 : adb shell monkey -p com.android.calculator2 -v -v -v 100
// 最详细的日志,包括了测试中选中/未选中的Activity信息
- 注意:在monkey测试完成时,最后一定会有一个:monkey finished标识。
- -p参数 <测试的包名列表>
- 在我们测试时,是针对具体的app进行测试的,所以在使用monkey测试时,我们需要提供具体的app包名给monkey,此时就需要用到参数-p,在-p后跟随app包名。
- 用此参数指定一个或多个包。指定包之后,monkey将只允许系统启动指定的app。如果不指定包, monkey将允许随机启动系统设备中的所有app。
- 指定一个包:adb shell monkey -p 包名 100
- 指定多个包:adb shell monkey –p 包名1 –p 包名2 100
- 示例: adb shell monkey -p com.tencent.mm -p com.wandoujia.phoenix2 100
- 说明:程序名称为包名,100是事件计数(即让Monkey程序模拟 100次随机用户事件)
- -s参数(复现随机点击的事件)
- S是种子值(seed),因为monkey是发送的是伪随机的事件流做压力测试,但是如果两次seed值相同,那
两次monkey测试所产生的事件序列也相同,所以一般在测试时要记录seed值,以防出现无响应和crash,不容易复现验证。
- 格式:adb shell monkey -s <seed> <event-count>
- 注意:-s需要跟在包名后,次数前
- 示例: 测试1:adb shell monkey -p com.wandoujia.phoenix2 –s 10 100
- 测试2:adb shell monkey -p com.wandoujia.phoenix2 –s 10 100
- 两次测试的效果是相同的,因为模拟的用户操作序列(每次操作按照一定的先后顺序所组成的一系列操作,
即一个序列)是一样的。操作序列虽 然是随机生成的,但是只要我们指定了相同的Seed值,就可以保证两次测试产生的随机操作序列是完全相同的,所以这个操作序列伪随机的。
- 这样对于我们发现异常后,以后复现bug有很大帮助,
- 比如当我们测试 adb shell monkey com.xxx–s 20 –v 10000发现有bug时,可以记录这个seed值,
然后可以回归测试bug有没修复。
- –throttle参数<毫秒>(设置事件间隔)
- 设置执行操作的延迟时间(毫秒)–是指两个事件(而非操作,如,触摸的事件共有up和down两个操作)之间的间隔,在事件之间插入固定延迟。通过这个选项可以减缓 Monkey 的执行速度。如果不指定该选项, Monkey 将不会被延迟,事件将尽可能快地被执行完成。(如执行100次若是没有事件间隔,基本上100次点击会在瞬间被完成,肉眼可能可以感受到被点击,但是无法明显的感觉到有那么多次。所以设定每次事件的间隔时常,是有必要的。为Monkey设定事件的间隔,使用–throttle参数。) 格式:adb shell monkey —throttle <milliseconds>
- 示例:adb shell monkey -p com.wandoujia.phoenix2 –throttle 3000 -v –v -v 100
- 调试选项
1)、–ignore-crashes(忽略崩溃)
- 用于指定当应用程序崩溃(Froce\Close)时,Monkey是否停止运行。正常情况下,如果在Monkey执行的阶段,出现了崩溃,会立即停止接下去的执行,如果使用此参数,即使应用程序崩溃,monkey依然会发送事件,直到事件计数完成。(在我们的实际工作中执行Monkey的时候,是在无人员干涉的,如想要它执行一夜,等等情况。那么如果出现崩溃就停止执行,明显不是我们需要的)。可以通过—ignore-crashes来忽略掉异常崩溃。格式:adb shell monkey —ignore-crashes <event-count>
2)、–ignore-timeouts(忽略超时无响应 或忽略ANR)
- 用于指定当应用程序发生ANR(Application No Responding(应用程序无响应))错误时,Monkey是否停止运行。如果使用此参数,即使应用程序发生ANR错误,Monkey依然会发送事件,直到事件计数完成。可以使用—ignore-timeouts参数。ANR是Android的一个错误,在页面无法响应事件的时候会报出来。一般遇到这样的情况,表示当前有耗时操作在UI线程指定,导致卡UI了。格式:adb shell monkey —ignore-timeouts <event-count>
3)、–ignore-security-exceptions(忽略安全异常)
- 用于指定当应用程序发生许可错误时(如证书许可,网络许可等),Monkey是否停止运行。如果使用此参数,即使应用程序发生许可错误,Monkey依然会发送事件,直到事件计数完成。
4)、–kill-process-after-error(发生错误后直接杀掉进程)
- 用于指定当应用程序发生错误时,是否停止其运行。如果指定此参数,当应用程序发生错误时,应用程序停止运行并保持在当前状态(注意:应用程序仅是静止在发生错误时的状态,系统并不会结束该应用程序的进程)。
5)、–monitor-native-crashes(跟踪本地方法的崩溃问题)
- 用于指定是否监视并报告应用程序发生崩溃的本地代码
6)、–hprof
- 该选项设置后,将会在monkey事件序列前后立刻生成report,大小为大于5MB,存储在/data/misc
- 现在Dalvik 虚拟机修改了,在收到SIGNAL_USR1信号的时候只会做GC,不会生成hprof文件。即:Monkey这个参数作废了。工作中为了保证测试数量的完整进行,我们一般不会在发生错误时立刻退出压力测试。monkey命令格式:adb shell monkey -p com.wandoujia.phoenix2 -s 500 –ignore-crashes –ignore-timeouts –monitor-native-crashes -v -v 1000 > F:\tool\20101.txt
3、事件类型
- monkey在发送伪随机事件时,是有不同的类型的。默认随机分配比例,也可以指定其百分比。如果不设置会是–pct-anyevent为100%,也就是纯随机事件;如果配置了其他参数,但是不够100%,余下的百分比部分也是–pct-anyevent事件。(在Monkey中,虽然输入的事件是随机产生的,但是可以指定输入事件类型的百分比,让其控制在我们需要的范围内。)如:
- 目前共包含11中类型的事件。Android 7.0 的11个事件,分别为:0:触摸事件–pct-touch
调整touch触屏事件的百分比,触碰事件就是指在屏幕上的一个单独位置的一次点击/抬起的事件。
- 1:滑屏事件–pct-motion(手势事件)
(手势事件是由一个在屏幕某处的按下事件、一系列的伪随机移动、一个抬起事件组成)即一个滑动操作,但是是直线的,不能拐弯
- 2:–pct-pinchzoom <percent> 2
调整二指缩放事件的百分比。(即智能机上的放大缩小手势操作)
- 3:轨迹球–pct-trackball
(轨迹球事件包括一个或多个随机移动,有时还伴有点击。轨迹球现在智能手机上已经没有了,就是类似手柄的方向键一样)
- 4:旋转(–pct-rotation)
调整屏幕旋转百分比。(如横屏、竖屏)
- 5:导航–pct-nav
调整“基本”导航事件的百分比 (导航事件由来自方向输入设备的上/下/左/右组成,现在智能机上基本也少了)。
- 6:主导航–pct-majornav
调整主要导航事件的百分比(如中间键、取消、确定或菜单引发的图形接口的动作)
- 7:系统按键–pct-syskeys
调整系统按键事件,如:home/back/startcall/endcall以及音量控制键等
- 8:app切换–pct-appswitch
调整启动activity的百分比,在随机间隔中,执行一个startActivity()方法调用,作为一种最大化的覆盖安装包的所有的activity的方法
- 9:键盘翻转(–pct-flip)10:随机–pct-anyevent
调整其他类型的事件的百分比,比如按键或其他不太常用到的一些事件的百分比
注意:自己指定的百分比之和不能超过100,否则会出错
例:adb shell monkey -p com.wandoujia.phoenix2 –throttle 3000 -v —pct-rotation 100 100
- 常用抓取LOG命令
1、adb shell top -m 10 -n 20 > c:\log\top.txt(top:打印CPU占用率最高的几个进程)
- -m num Maximum number of processes to display. 最多显示多少个进程-n num Updates to show before exiting. 刷新次数
- VSS – Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
- RSS – Resident Set Size 实际使用物理内存(包含共享库占用的内存)
- PSS – Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
- USS – Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
(2)2、adb shell dumpsate > dumpsys.txt
dumpstate:打印手机现在的状态,包含了很多内容,比如CPU占用率,当前运行到哪一行代码,系统的属性等,“系统忙,….无响应”很多是由于死锁引起的,dumpstate对解决这类问题很有用;)
- adb shell logcat /proc/kmsg > c:\log\kmsg.txt
kmsg 、kernel:打印的是内核信息
4、adb pull /data/dontpanic c:\log
dontpanic:打印的是手机的数据中的堆栈信息
5、adb pull /data/anr c:\log
anr:弹出 “应用程无响应 等待 强制关闭”这个对话框时留下来的信息。
6、adb shell logcat > E:\log\logcat.txt
缓存区的LOG信息
7、adb logcat -b radio
记录无线通讯日t
- Monkey连接模拟器测试
- 安装并打开模拟器 ,
- 在 cmd模式下连接模拟器
adb connect 127.0.0.1:62001 –连接adb
3、查看设备是否连接成功:
adb devices (进入adb 检查模拟器是否上线)
4、找到所测试的APP的包名
5、执行monkey命令
例:使用Monkey对计算器程序进行压力测试:
Monkey压力测试出了一个bug
输出日志到本地目录:
adb shell monkey –p com.android.calculator2 -v 500 > 本地目录\XXX.log
- Monkey真机测试
1、连接步骤:
1)使用USB数据线连接PC和手机
2)安装手机驱动程序
3)允许USB调试 – – 确定
4)输入adb devices,查看设备是否连接成功
5)找到所测试的APP的包名
6)执行monkey命令
2、设备授权
一键清空所有已授权的电脑,关闭USB调试,再连接手机,再接受USB调试
- Monkey 日志分析
- 运行日志
C:\Users\Administrator>adb shell monkey -p com.android.calculator2 -v -v 10
:Monkey: seed=55 count=10 //伪随机种子为5,事件总数10
:AllowPackage: com.android.calculator2 //测试包名
:IncludeCategory: android.intent.category.LAUNCHER //包的类别
:IncludeCategory: android.intent.category.MONKEY
// Selecting main activities from category android.intent.category.LAUNCHER //选择主activities
// – NOT USING main activity com.android.vending.AssetBrowserActivity (from packagecom.android.vending) //不被测试的包的activity
// – NOT USING main activity com.android.contacts.activities.PeopleActivity (from package
com.android.contacts)
// – NOT USING main activity com.android.camera.CameraLauncher (from package com.android.camera2)
// – NOT USING main activity com.android.calendar.AllInOneActivity (from package
com.android.calendar)
// Seeded: 55 //随机种子
// Event percentages: //事件百分比
// 0: 15.0%
// 1: 10.0%
// 2: 2.0%
// 3: 15.0%
// 4: -0.0%
// 5: 25.0%
// 6: 15.0%
// 7: 2.0%
// 8: 2.0%
// 9: 1.0%
// 10: 13.0%
:Switch:
//表示跳转到com.android.calculator2里面的Calculator这一个Activity里
#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;
launchFlags=0x;component=com.android.calculator2/.Calculator;end
//允许此Intent跳转( Intent在android中起着一个媒体中介的作用,它是一个对象,专门提供组件间互
相调用的相关信息)
// Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER]
cmp=com.android.calculator2/.Calculator } in package com.android.calculator2
Sleeping for 0 milliseconds //事件间的延迟思考时间为0
// 下列为发送的些操作,如点击按下,点击放开,触摸移动
:Sending Key (ACTION_DOWN): 172 // KEYCODE_GUIDE
:Sending Key (ACTION_UP): 172 // KEYCODE_GUIDE
Sleeping for 0 milliseconds
:Sending Touch (ACTION_DOWN): 0:(804.0,229.0) //坐标系
:Sending Touch (ACTION_UP): 0:(809.7128,228.16101)
Sleeping for 0 milliseconds
:Sending Trackball (ACTION_MOVE): 0:(4.0,4.0) //轨迹球
:Sending Trackball (ACTION_MOVE): 0:(-1.0,-3.0)
:Sending Trackball (ACTION_MOVE): 0:(-2.0,-1.0)
:Sending Trackball (ACTION_MOVE): 0:(-2.0,3.0)
:Sending Trackball (ACTION_MOVE): 0:(1.0,-2.0)
Events injected: 10 //注入事件数为10
:Sending rotation degree=0, persist=false // 发送屏幕翻转度=0,存留=假
:Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0 //丢弃:键=0,指针=0,轨迹球=0,
键盘轻弹=0,屏幕翻转=0
Network stats: elapsed time=58ms (0ms mobile, 0ms wifi, 58ms not connected) // 网络状态:
占用时间=58ms(0ms用在手机上, 0ms用在无线网络中,没有连接是 58ms)
// Monkey finished //monkey测试完毕
从例子中可以看出,该程序在这次测试中没有问题,若程序出现问题终端将打印出异常供开发人员查找错误
- 1、异常情况
Monkey 测试出现错误后,看Monkey的日志 (注意第一个swith以及异常信息, log中存在的 ANR、
Exception、Switch、GC、crash几个单词)
- 程序无响应的问题: 在日志中搜索 “ANR ”(Application No Response )崩溃问题:在日志中搜索 “CRASH” (如果出现空指针,可以搜索“Exception”因 NullPointerException)
肯定是有bug
- 错误:在日志中搜索”ERROR”
- 2、异常情况处理
unknown host service
主要是由于5037端口被占用,sdk中的adb无法启动,
- 1)使用netstat -aon | findstr “5037” 找出这个进程PID,
- 2)然后使用taskkill /pid 进程PID 或者任务管理器关掉该进程
- 3)重启ADB服务
- 3、故障及排除方法
INSTALL_FAILED_NO_MATCHING_ABIS错误
- 表示AVD中使用了与当前CPU架构不一致的native libraries,需要修改CPU类型从intel为ARM
- App名称拼错了一个单词
- Android单词拼错了
- 关于设备状态错误方面可以使用下列三个命令后再重试设备是否上线
adb kill-server
adb start-server
adb remount(重新安装)
- 4、对monkey运行出来错误日志分析
- 1)最常见的崩溃,空指针:NullPointerException 这个异常大家肯定都经常遇到,可以搜索FATAL,如下信息,可以找到关键字NullPointerException
- 01-04 05:02:02.691: E/AndroidRuntime(12282): FATAL EXCEPTION: main
- 01-04 05:02:02.691: E/AndroidRuntime(12282): Process: com.elan.activity, PID: 12282
- 01-04 05:02:02.691: E/AndroidRuntime(12282): java.lang.RuntimeException:
Unable to create application com.elan.elanutil.MyApplication: java.lang.NullPointerException
- 01-04 05:02:02.691: E/AndroidRuntime(12282):
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4544)
- 01-04 05:02:02.691: E/AndroidRuntime(12282): at
android.app.ActivityThread.access$1500(ActivityThread.java:151)
- 2)越界:IndexOutOfBoundsException,这个也是比较常见的,异常的解释是”数组下标越界”,
注意关键字:CRASH,后面跟着的是软件的包名
// CRASH: com.xxx (pid 30799)
// Short Msg: java.lang.IndexOutOfBoundsException
// Long Msg: java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
// Build Label: U900/hct82_cwet_td/hct82_cwet_td:4.4.2/KOT49H/:eng/tes
- 3)算术异常类:illegalargumentexception,这个异常的解释是”方法的参数错误”比如音量调节方法中的音量参数如果写成负数就会出现这个异常
还有其它的:illegalaccessexception(没有访问权限),IllegalStateException等等长的差不多
09-30 10:26:12.620: E/AndroidRuntime(12444): FATAL EXCEPTION: main
09-30 10:26:12.620: E/AndroidRuntime(12444): java.lang.IllegalArgumentException: View not attached to window manager
09-30 10:26:12.620: E/AndroidRuntime(12444): at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:355)
09-30 10:26:12.620: E/AndroidRuntime(12444): at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:200)
- 4)文件未找到异常:FileNotFoundException
- 5)指定的类不存在:ClassNotFoundException
- 5)其它异常:
类型强制转换异常:ClassCastException
数组负下标异常:NegativeArrayException
违背安全原则异常:SecturityException
文件已结束异常:EOFException
字符串转换为数字异常:NumberFormatException
操作数据库异常:SQLException
输入输出异常:IOException
方法未找到异常:NoSuchMethodException
- 6)忽略异常
1)–ignore-crashes 忽略崩溃:抱歉,“XX”已停止运行,也就是通常说的crash
2)–ignore-timeouts 忽略超时:界面弹出程序无响应框,也就是ANR
3)–ignore-security-exceptions 忽略安全异常
4)–ignore-native-crashes 忽略本地异常崩溃
如我们执行以下指令:adb shell monkey –p com.XXX –ignore-crashes –ignore-timeouts –ignore-security-exceptions –ignore-native-crashes -v >d:/test.txt
这样就可以执行20万次不会中途停止
- 7)Monkey内存泄漏
- 测试时弹出 out of memory对话框
- 查看logcat中是否有GC相关字段(两个cmd窗口先运行logcat命令,再运行Monkey,Monkey
结束后Ctrl C中断logcat抓取):
- GC_FOR_ALLOC, 因为在分配内存时内存不够引发的
- GC_EXPLICIT, 表明GC被显式请求触发的,如System.gc调用
- GC_CONCURRENT, 表明GC在内存使用率达到一定的警戒值时,自动触发
- GC_BEFORE_OOM, 表明在虚拟机抛出内存丌够异常OOM之前,执行最后一次回收内存垃圾
- 如何重现BUG
1、找到是monkey里面的哪个地方出错
2、查看Monkey里面出错前的一些事件动作,并手动执行该动作
3、若以上步骤还不能找出,可以使用之前执行的monkey命令再执行一遍,注意seed值要一样
- monkey的测试策略
- 单个apk的验收测试时,使用单一apk且不忽略异常的命令执行单个apk的解决问题的测试时,使用单一apk且忽略异常的命令执行。这样可以在一次执行的过程中发现应用程序中的多个问题。单个apk的应用程序的压力性测试时,主要缩短monkey测试中事件与事件之间的延迟时间,验证在快速的事件响应的过程中,程序是否能正常运行。将–throttle的值设定为500或者更小,一般都使用500毫秒的延迟事件。在进行apk的集合测试(测试对象为多个APP,手机测试?)时,对于高频率使用的apk、长时间使用的apk都要包含在执行的应用程序中间。APK分类具体:高频率使用的apk如:Phone、Contacts、Message、Settings、File Manager、Gallery、Input Method长时间使用的apk如:Phone、Browser、Music player、Camera、Video player、Email、Chat其他的apk如:Calendar、Notepad、Calculator、FM Radio、Google Search
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/85614.html