monkey压力测试
一、介绍
Monkey测试原理:Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中。
它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试。
Monkey测试是一种为了测试软件的稳定性、健壮性的快速有效的方法。
二、环境搭建
SDK搭建:略
模拟器下载和配置(真机不需要这一步,推荐模拟器:夜神、闪电)
adb文件替换(模拟器):把模拟器安装目录下的adb.bat文件复制到SDK(SDK\platform-tools)目录下替换。
三、随机测试实现
1、确定链接设备
在SDK的platform-tools下进入CMD窗口,执行命令:adb devices 获取链接的设备信息
真机需要链接电脑并且开启开发者模式的调试;
模拟器需要打开模拟器;
2、获取需要测试app的包名等信息:
在上一步的cmd窗口输入命令:aapt dump badging D:\XXX.apk(xxx指安装包名,D:\是指路径)【也可以输入命令:aapt dump badging 后把app拖入cmd窗口】
在读取的信息中就可以看到包名
3、执行monkey命令
还是上面的cmd窗口执行命令:adb shell monkey -p 包名 -v 100
adb shell monkey:monkey测试的通用命令代表听过shell启动执行monkey命令
-p 包名:指定需要执行的app,会自动打开需要执行的app,这里需要提前安装app【adb install 安装包路径 进行安装,或者手动拖动到模拟器安装】
-v:用于指定反馈信息级别(信息级别就是日志的详细程度),总共分3个级别:-v ,-v -v ,-v -v -v (v越多越详细)
100:随机事件的数量
【强制关闭monkey】1、adb shell ps 查看全部在运行的进程,查找出com.android.commands.monkey 进程PID。使用命令:adb shell kill pid 杀掉monkey进程
四、操作事件讲解
Monkey所执行的随机事件流中包含11大事件,分别是触摸事件、手势事件、二指缩放事件、轨迹事件、屏幕旋转事件、基本导航事件、主要导航事件、系统按键事件、
启动Activity事件、键盘事件、其他类型事件。Monkey通过这11大事件来模拟用户的常规操作,对手机App进行稳定性测试。
4、轨迹事件:轨迹事件是由一个或多个随机的移动组成的,有时会伴随着点击,现在的手机几乎都没有轨迹球,但轨迹球事件中包含曲线滑动操作
6、基本导航事件:基本导航事件是指点击方向输入设备的上、下、左、右按键的操作,现在手机上很少有上、下、左、右按键,这种事件一般用得比较少
7、主要导航事件:如键盘的中间键、回退按键、菜单按键
8、系统按键事件:系统按键事件是指点击系统保留使用的按键的操作,如点击Home键、返回键、音量调节键等
9、启动Activity事件:在手机上启动一个Activity的操作
11、其他类型事件:包括了除前面提到的10种事件外其他所有的事件,如按键、其他不常用的设备上的按钮等
五、参数介绍
1、基本参数
(1)-p:用此参数指定一个或多个包
指定一个包:adb shell monkey -p com.taobao.litetao 100
指定多个包:adb shell monkey -p fishjoy.control.menu –p com.taobao.litetao 100
(2)-v:用与指定反馈信息级别(信息级别就是日志的详细程度),总共分3个级别
Level 0 : adb shell monkey -p com.taobao.litetao -v 100 // 缺省值,仅提供启动提示、测试完成和最终结果等少量信息
Level 1 : adb shell monkey -p com.taobao.litetao -v -v 100 // 提供较为详细的日志,包括每个发送到Activity的事件信息
Level 2 : adb shell monkey -p com.taobao.litetao -v -v -v 100 // 最详细的日志,包括了测试中选中/未选中的Activity信息
(3)-s:用与指定伪随机数生成器的seed值,如果seed相同,则两次Monkey测试所产生的事件序列也相同的
adb shell monkey -p com.taobao.litetao –s 10 100
(4)--throttle:用与指定用户操作(即事件)间的时延,单位是毫秒【每一个指令之间加上固定的间隔时间】
adb shell monkey -p com.shjt.map --throttle 3000 100
(5)>d:\monkeylog.txt:导出测试日志
adb shell monkey -v -v 100 >d:\monkeylog.txt
标准流和错误流分开保存:
adb shell monkey -v 100 1>d:\monkey.log 2>d:\error.log
2、事件类参数
(1)-f:执行指定脚本
adb shell monkey -f /mnt/sdcard/test1【这是脚本路径】
(2)--pct-touch:调整触摸事件百分比
adb shell monkey -v -v --pct-touch 100 200
注意:触摸事件不单单是按键,它泛指发生在某一位置的一个down-up事件
注意:所有事件的百分比总和不能超过100
(3)--pct-motion:调整手势事件百分比
adb shell monkey -v -v --pct-motion 100 200
(4)--pct-app-switch:调整应用启动事件的百分比
adb shell monkey --pct-appswtich 100 200
(5)--pct-rotation:调整屏幕旋转事件百分比
adb shell monkey --pct-rotation 100 200
(6)--pct-syskeys:系统按键事件百分比
(7)--pct-anyevent:其他事件
3、调试类参数
(1)--ignore-crashes:应用程序崩溃后继续发送事件
adb shell monkey --ignore-crashes
【在设置此选项后,当应用程序崩溃或发生失控异常时,monkey将继续运行直到计数完成。如果不设置此选项,monkey遇到上述崩溃或异常将停止运行】
(2)--ignore-timeouts:在任何超时错误发生后继续发送事件
adb shell monkey --ignore-timeouts
(3)--ignore-security-exceptions:应用程序权限错误发生后继续发送事件
adb shell monkey --ignore-security-exceptions
4、测试命令执行:
adb shell monkey -p com.taobao.litetao
--pct-touch 40 --pct-motion 25
--pct-appswitch 10
--pct-rotation 5
-s 1666 --throttle 400
--ignore-crashes
--ignore-timeouts
-v -v 200
六、测试结果分析(日志分析)
1、读懂测试结果
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
# 指明本次的seed和执行次数、app包名
:Monkey: seed=1642132691552 count=200
:AllowPackage: com.ushaqi.zhuishushenqi
:IncludeCategory: android.intent.category.LAUNCHER
:IncludeCategory: android.intent.category.MONKEY
'''各种事件所占的比例'''
// Event percentages:
// 0: 15.0%
// 1: 10.0%
// 2: 2.0%
// 3: 15.0%
// 4: -0.0%
// 5: -0.0%
// 6: 25.0%
// 7: 15.0%
// 8: 2.0%
// 9: 2.0%
// 10: 1.0%
// 11: 13.0%
# 表示跳转到com.ushaqi.zhuishushenqi里面的NotesList这一个Activity里
:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.ushaqi.zhuishushenqi/.ui.SplashActivity;end
# 允许此Intent跳转
// Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.ushaqi.zhuishushenqi/.ui.SplashActivity } in package com.ushaqi.zhuishushenqi
# 发送的一些动作
:Sending Trackball (ACTION_MOVE): 0:(4.0,0.0)
:Sending Touch (ACTION_DOWN): 0:(323.0,1169.0)
:Sending Touch (ACTION_UP): 0:(408.41333,1067.6368)
:Sending Trackball (ACTION_MOVE): 0:(-4.0,-4.0)
:Sending Trackball (ACTION_MOVE): 0:(-5.0,-1.0)
:Sending Touch (ACTION_DOWN): 0:(27.0,741.0)
:Sending Touch (ACTION_UP): 0:(97.5283,818.68567)
:Sending Trackball (ACTION_MOVE): 0:(-2.0,-3.0)
:Sending Touch (ACTION_DOWN): 0:(166.0,1241.0)
:Sending Touch (ACTION_UP): 0:(186.76784,1280.0)
:Sending Trackball (ACTION_MOVE): 0:(-1.0,-3.0)
:Sending Trackball (ACTION_MOVE): 0:(0.0,-4.0)
//[calendar_time:2022-01-13 13:58:41.070 system_uptime:55707]
// Sending event #100
:Sending Touch (ACTION_DOWN): 0:(129.0,494.0)
:Sending Touch (ACTION_UP): 0:(122.64248,488.92212)
:Sending Touch (ACTION_DOWN): 0:(45.0,1275.0)
:Sending Touch (ACTION_UP): 0:(58.485413,1280.0)
:Sending Touch (ACTION_DOWN): 0:(327.0,68.0)
:Sending Touch (ACTION_UP): 0:(390.11304,129.39902)
:Sending Trackball (ACTION_MOVE): 0:(1.0,-5.0)
// Allowing start of Intent { cmp=com.ushaqi.zhuishushenqi/com.sensorsdata.sf.ui.view.DialogActivity } in package com.ushaqi.zhuishushenqi
:Sending Touch (ACTION_DOWN): 0:(531.0,278.0)
:Sending Touch (ACTION_UP): 0:(525.7864,280.80414)
:Sending Touch (ACTION_DOWN): 0:(346.0,1062.0)
:Sending Touch (ACTION_UP): 0:(256.71973,1169.7059)
:Sending Touch (ACTION_DOWN): 0:(79.0,705.0)
:Sending Touch (ACTION_UP): 0:(39.33467,661.97534)
:Sending Touch (ACTION_DOWN): 0:(145.0,351.0)
:Sending Touch (ACTION_UP): 0:(203.19296,366.69592)
// Allowing start of Intent { cmp=com.ushaqi.zhuishushenqi/com.android.zhuishushenqi.module.baseweb.view.ZssqWebActivity } in package com.ushaqi.zhuishushenqi
// activityResuming(com.ushaqi.zhuishushenqi)
:Sending Touch (ACTION_DOWN): 0:(132.0,415.0)
:Sending Touch (ACTION_UP): 0:(126.71823,425.3338)
:Sending Touch (ACTION_DOWN): 0:(462.0,151.0)
:Sending Touch (ACTION_UP): 0:(555.9698,93.7883)
:Sending Trackball (ACTION_MOVE): 0:(-4.0,3.0)
// Rejecting start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.android.chrome/com.google.android.apps.chrome.Main } in package com.android.chrome
// Allowing start of Intent { cmp=com.ushaqi.zhuishushenqi/com.android.zhuishushenqi.module.login.view.ZssqLoginActivity } in package com.ushaqi.zhuishushenqi
:Sending Touch (ACTION_DOWN): 0:(263.0,175.0)
:Sending Touch (ACTION_UP): 0:(275.37122,174.74803)
:Sending Touch (ACTION_DOWN): 0:(187.0,899.0)
:Sending Touch (ACTION_UP): 0:(194.94337,897.5777)
:Sending Trackball (ACTION_MOVE): 0:(-5.0,-5.0)
Events injected: 200
:Sending rotation degree=0, persist=false
# 丢弃的,键=0,指针=0,轨迹球=0,翻转=0
:Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0
# 网络统计经过时间为4069ms,其中4069ms是用于在手机上的,0ms用于无线网络上,没有连接的时间为0ms
## Network stats: elapsed time=4069ms (0ms mobile, 0ms wifi, 4069ms not connected)
// Monkey finished
2、测试结果初步判断
Monkey测试出现错误后,一般的差错步骤为以下几步:
(1) 找到是monkey里面的哪个地方出错
(2) 查看Monkey里面出错前的一些事件动作,并手动执行该动作
(3) 若以上步骤还不能找出,可以使用之前执行的monkey命令再执行一遍,注意seed值要一样
测试结果分析:搜索关键词:ANR、 Exception、 Null、 Error、 crash(Fatal)
(1)程序无响应的问题:在日志中搜索 “ANR”
在Android上,如果你的应用程序有一段时间响应不够灵敏(5秒内没有输入响应事件),系统会向用户显示一个对话框,
这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框
(2)崩溃问题:在日志中搜索 “Exception” ,在这里顺便提一下常见的Java异常
算术异常类:ArithmeticExecption
空指针异常类:NullPointerException
类型强制转换异常:ClassCastException
数组负下标异常:NegativeArrayException
数组下标越界异常:ArrayIndexOutOfBoundsException
违背安全原则异常:SecturityException
文件已结束异常:EOFException
文件未找到异常:FileNotFoundException
字符串转换为数字异常:NumberFormatException
操作数据库异常:SQLException
输入输出异常:IOException
违法访问错误:IllegalAccessError
内存不足错误:OutOfMemoryError
堆栈溢出错误:StackOverflowError
其他
七、异常分析
1、Null指针异常
空指针异常主要是有NullPointerException异常提示,在Monkey测试过程中,该信息一般记录在plog.log (locat中也有该信息)中
如果Monkey命令被中断该进程出现异常,
异常信息主要是由于NullPointerException引起的,也就是出现了空指针,导致了acore进程进入debug
具体的可以继续分析是由哪个函数的那一行导致的,如可以从rollAnimate3dRotate.java文件中的275行查找等
可能同一应用中存在多处的空指针异常,所以一旦出现空指异常后,可以分析和对比log信息,如果不一致的话,需要把新的log信息也一同添加到bug中,
如果log信息一直的话,则不需要继续补充没有必要的log信息
2、debug异常
debug异常主要是由于应用程序本身的错误导致的异常,出现的该问题,很可能在手动测试时也可以测试到
该进程进入debug
出现的是IllegalStateException异常,该异常一般多是传递的参数非法或被多次调用时出现的异常
3、低内存异常
低内存异常一般情况下,主要表现在出现OutOfMemoryError异常或者提示Out of memory,其后果同样表现为抛出OutOfMemoryError异常或者是通过
kill process 来杀掉部分进程以释放内存空间,当然如果被kill点关键的进程的话,也就可能导致部分应用会自动的退出。出现该情况时,
主要是在进行频繁的进行大量的操作导致的,所以使用手动的方式也是可能进行重现的
进程出现的异常
出现的是OutOfMemoryError异常,该异常一般多频繁的操作(即多次调用某个函数,存在申请变量空间未释放)导致的
4、操作无响应异常
操作无响应的问题,主要表现在Monkey运行过程中,出现某功能无响应,提示是否“强制关闭“或“等待“
进程出现的无响应
出现的是TimerOut异常,该异常一般出现时一般都会又keyDispatchingTimedOut提示