ADB Monkey Stress/Stability Test Solution-Android Test

1. Introduction to ADB Monkey

ADB Monkey is a program that runs on an emulator or device and generates a stream of pseudo-random user events (such as clicks, taps, or gestures) as well as many system-level events. Generally we will use it for stability testing and stress testing

We can use Monkey to stress test the application under development in a random and repeatable manner.

Monkey is a command-line tool that can be run on any emulator instance or device. It sends a stream of pseudo-random user events into the system to stress test the application software you are developing.

Monkey includes many options, which fall into four main categories:

  • Basic configuration options, such as setting the number of events to try.

  • Operational constraints, such as restricting test objects to a single package.

  • Event type and frequency.

  • Debug options.

When the Monkey runs, it generates events and sends them to the system. It also monitors the system under test and looks for three special conditions:

  • If you have restricted Monkey to run in one or more specific packages, it monitors and blocks attempts to switch to any other package.

  • If the app crashes or receives any unhandled exceptions, Monkey stops and reports the error.

  • If the application generates an "Application Not Responding" error, Monkey stops and reports the error.

Depending on the level of detail you choose, you'll also see reports on Monkey's progress and generated events.

2. Basic Usage

We have now understood what Monkey is, and what method is used to conduct a stress test on our software package, so now, we should learn about one of his gameplays.


2.1 Test equipment connection

Before any operation starts, we should first connect to our test equipment through PC and set up the stage.

The device we're using here: Samsung's Galaxy S21 5G phone

After selecting our device, we connect the Type-C port of the mobile phone to the PC data port using a data cable, and open the USB debugging port in the developer tool (here Samsung is an example: the entry is: Settings->Developer Options -> Usb Debugging)

After setting up the stage (connecting the mobile phone), we will officially start our testing journey~

2.2 Monkey startup method:

There are several ways to start Monkey (you can start Monkey from the command line on your development computer, or you can start it from a script)

一般我们使用PC的cmd启动会较多,这里只是对此进行介绍,在实际使用时直接通过我们命令行加上操作的命令选项即可。介绍如下:

2.2.1 PC端Cmd启动

adb shell monkey + 命令选项

由于 Monkey 在模拟器/设备环境中运行,因此我们必须从该环境中通过 shell 启动它。为此,我们可以在每个命令前面加上 adb shell,或者直接进入 shell 后并输入 Monkey 命令。

例:adb shell monkey --help(输出简单的使用指南)

例:adb shell(进入shell,进入后可通过exit命令退出)

2.2.2 Android手机直接执行Monkey命令选项

2.2.3 PC进入Android系统执行Monkey命令选项

2.3 命令选项参考中文文档

Monkey官方中文文档

2.4测试命令

我们安装jdk1.8.0时,一般会带有adb的,所以安装部分我们这里就不进行过多展示了,如果想确认电脑是否有安装adb monkey,我们使用命令查询一下版本号即可,若无再去补充安装。

2.4.1 查看版本号

adb version

(出现版本号即电脑已安装了adb Monkey,可直接使用)

adb devices

2.4.2 查看PC连接设备

(在以上部分操作中,我们已经对我们的测试设备进行了设备连接,我们测试前应该确认我们当前连接设备是否正确,显示我们测试设备如上)

2.4.3安装测试软件包

(我们测试包如下,安装包存放在桌面,我们首先得使用cd命令,在cmd中进入到安装包保存路径桌面,再使用代码进行安装包安装。路径:C:\Users\JOYY\Desktop。使用命令install安装)

adb install xxx.apk

2.4.4获取软件包名

安装完成以后,我们就需要对我们安装的或者正在运行的程序进行测试,但安装完成后,我们并不知道程序的一个包名是什么,所以我们就需要对此进行获取,找到程序软件的包名,对此进行测试。

(获取软件包名有两种方法,如下:)

adb shell dumpsys window w | findstr \/ | findstr name=
//获取正在执行的app程序包名,一般先点击打开程序,在执行此命令
adb shell pm list package -f
//获取手机内所有apk对呀的包名及路径

获取我们安装后使用的包名如下:com.rosetta.lavaclass (一下代码均以com.xxx.xxx替换包名)

msurface中的name即是应用的包名:mSurface=Surface(name=com.rosetta.lavaclass)

2.5压力测试

获取包名后,我们即可对该包针对性压力测试,当然也可以对测试设备进行无差别点击测试

(区别就在于,一个是只在这个软件中随机点击,一个是在设备整个显示页面中随机点击)

2.5.1 页面中随机点击(随机启动APP发送随机事件)
adb shell monkey +随机次数
2.5.2 指定单个包随机点击(-p后面跟需要单个测试的包名字)
adb shell monkey -p com.xxx.xxx +随机次数
2.5.3 指定多个包进行随机点击
adb shell monkey -p com.xxx.xxx -p com.xxx.xxx +随机次数
2.5.4 在指定点击时,加入毫秒时间间隔
adb shell monkey -p com.xxx.xxx --throttle 300 +随机次数
//每300毫秒后再随机点击一次(即事件间延迟)
2.5.5重复上一次的点击

Monkey虽然是随机点击的,但是我们主要是用它来做压力测试。所以如果在碰到崩溃的时候,我们也不确定做了什么,因此我们需要重复我们之前的随机事件,再来一次看崩溃的问题。所以我们就需要用到-s

adb shell monkey -p com.xxx.xxx -s 10 100
//第一次运行:指定seed数10,第二次若seed还是10,则两次monkey测试所产生的事件序列也相同,就是重复用户操作序列
adb shell monkey -p com.xxx.xxx -s 10 100
//第二次运行:应该与第一次运行的产生事件一致相同

第一次运行:

第二次运行:

2.5.6设置测试事件命令百分比

事件说明:

Monkey的事件类型总共有11种,分别是触摸(Touch)、手势(motion)、二指缩放(pinchzoom)、轨迹(trackball)、旋转(rotation)、基本导航(nav)、主要导航事件(majornav)、系统按键(syskeys)、启动activity(appswitch)、键盘事件(flip)和其它类型事件(anyevent),在日志中分别用0-10来表示,若要对此进行设置,则在对应英文前加--pct-xxx放入命令行;如果不指定事件的百分比,Monkey会随机按事件百分比来跑APP;

adb shell monkey -p com.xxx.xxx --pct-touch 20 1000
//指定触摸事件的百分比
adb shell monkey -p com.xxx.xxx --pct-motion 30 1000
//指定手势动作事件的百分比
adb shell monkey -p com.xxx.xxx --pct-touch 20--pct-pinchzoom 30 --pct-motion 15 --pct-appswitch 301000
//指定多个事件的百分比
2.5.7 其他主要参数设置

我们再使用Monkey进行测试app时,我们一般都需要较长时间的稳定性测试,比如连续测试10小时或者更久(PS:Monkey并不能指定特定时间,不过可以指定次数,时间的话可以在日志基础上大概模糊运算),测试的一个过程中,App很可能就因为测试时间不久,因为碰到问题而崩溃,此时测试会暂停运行,而达不到我们长期测试的目的,这时我们就需要通过调试参数来让测试执行继续长久执行下去,记录崩溃并持续发送执行事件。

adb shell monkey -p com.xxx.xxx --ignore-crashes 1000
//--ignore-crashes指即使应用程序崩溃(Force&Close错误),Monkey依然会发送执行事件,直到事件达到指定的次数1000

adb shell monkey -p com.xxx.xxx --ignore-security-exceptions 1000
//--ignore-security-exceptions指APP发生许可证书错误时,Monkey依然会发送执行事件,直到事件达到指定的次数1000

adb shell monkey -p com.xxx.xxx --ignore-timeouts 1000
//--ignore-timeouts指APP应用程序发生ANR错误时,Monkey依然会发送执行事件,直到事件达到指定的次数1000

adb shell monkey -p com.xxx.xxx --kill-process-after-error 1000
//--kill-process-after-error指APP发生错误时,应用程序暂停运行并保持在当前状态

adb shell monkey -p  com.xxx.xxx --ignore-timeouts --ignore-crashes 1000
//当然我们也可以多个控制主要参数一起使用,以上是遇到崩溃及遇到ANR都会保持执行
2.5.8 综合运用
adb shell monkey -p com.xxx.xxx --throttle 500 --ignore-crashes 
--ignore-timeouts --ignore-security-exceptions --ignore-native-crashes 
--monitor-native-crashes -v -v -v 1000>d:\MonkeyTestLog.txt

2.6 获取日志

当然,我们单纯的随机执行点击还不够我们了解我们都发生了什么,有没有出现异常,这时候我们就必须获取一下我们执行的日志并进行分析

  • Monkey输出的日志,一共有三个级别,我们都可以通过-v来设置输出日志的级别

  • -v(第一级别) -v -v (第二级别) -v -v -v(第三级别)

adb shell monkey -v +随机次数
//随机打开app并随机点击次数,展示日志为第一级别,展示仅提供启动提示、测试完成和最终结果等少量信息
adb shell monkey -p com.xxx.xxx -v -v +随机次数
//指定单个包随机点击,展示日志为第二级别,展示包括每个发送到Activity的信息。
adb shell monkey -p com.xxx.xxx -p com.xxx.xxx -v -v -v+随机次数
//指定多个包进行随机点击,展示日志为第三级别,展示包括了测试中选中/未选中的Activity信息

我们在页面中展示日志终究还是不利于我们分析日志,为了方便分析日志,我们可以通过Monkey的命令进行Log的打印并保存在电脑本地,以便查看。

2.6.1将日志保存在电脑
adb shell monkey -p com.xxxx.xxx -v -v -v 1000 > Desktop/MonkeyTestLog.txt
//该条语句指的是在桌面生成一个MonkeyTestLog.txt文件,存放指定包运行1000次的三级日志
2.6.2 将日志保存在手机
adb shell
monkey -p com.xxx.xxx -v -v -v 1000 > /mnt/sdcard/MonkeyTestLog.txt
//将运行日志保存在手机sd卡目录中
2.6.3 区分保存常规日志与错误日志
adb shell monkey -p com.xxx.xxx -v -v -v 1000 1>d:\MonkeyTestone.txt 2>F:\MonkeyeTesttwo.txt
//将获取的日志区分保存,1为常规日志;2为错误日志。以便更好的查找定位问题

2.6.1运行后,我们就可以在桌面上看到我们的日志Log文件啦

2.7 分析日志

现在我们已经将我们随机点击的次数产生的日志Log拿到手了,现在我们就要对这个日志进行分析。

Monkey 运行时输出的日志Log一般会包含有四类信息

a.测试命令信息

b.伪随机事件流信息

c.异常信息

d.Monkey 执行结果信息

2.7.1 测试命令信息
// 测试命令信息
Monkey: seed=10 count=100
// 随机种子值,执行事件数量
AllowPackage: com.xxx.xxx
// 可运行的应用列表
IncludeCategory: android.intent.category.LAUNCHER
IncludeCategory: android.intent.category.MONKEY
//Category 包含LAUNCHER 和MONKEY
// 各事件的百分比
// Event percentages:
// 0: 15.0% 事件0 :--pct-touch       //触摸(屏幕按下抬起)
// 1: 10.0% 事件1 :--pct-motion      //手势(按下随机移动)
// 2: 2.0% 事件2 :--pct-pinchzoom    //二指缩放(屏幕放大缩小)
// 3: 15.0% 事件3 :--pct-trackball   //轨迹(曲线滑动)
// 4: -0.0% 事件4 :--pct-rotation    //旋转(屏幕旋转)
// 5: 25.0% 事件5 :--pct-nav         //基本导航(设备上下左右按键)
// 6: 15.0% 事件6 :--pct-majornav    //主要导航(回退主屏幕菜单)
// 7: 2.0% 事件7 :--pct-syskeys      //系统按键(点击Home或点击音量调节)
// 8: 2.0% 事件8 :--pct-appswitch    //启动activity(打开某个应用activity页面)
// 9: 1.0% 事件9 :--pct-flip         //键盘事件(键盘操作事件)
// 10: 13.0% 事件10 :--pct-anyevent  //其他类型事件
2.7.2 伪随机事件流信息
:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.rosetta.lavaclass/.ui.launch.LaunchActivity;end
// Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.rosetta.lavaclass/.ui.launch.LaunchActivity } in package com.rosetta.lavaclass
// 执行的事件流信息
:Sending Trackball (ACTION_MOVE): 0:(1.0,1.0)
:Sending Touch (ACTION_DOWN): 0:(988.0,1070.0)
:Sending Touch (ACTION_UP): 0:(1015.05676,1080.0)
:Sending Trackball (ACTION_MOVE): 0:(4.0,2.0)
:Sending Trackball (ACTION_UP): 0:(0.0,0.0)
:Sending Touch (ACTION_DOWN): 0:(1835.0,728.0)
:Sending Touch (ACTION_UP): 0:(1828.2017,726.7519)
:Sending Touch (ACTION_DOWN): 0:(1608.0,573.0)
:Sending Touch (ACTION_UP): 0:(1618.8567,567.05707)
:Sending Touch (ACTION_DOWN): 0:(2099.0,1079.0)
:Sending Touch (ACTION_UP): 0:(2097.8943,1080.0)
:Sending Touch (ACTION_DOWN): 0:(232.0,132.0)
:Sending Touch (ACTION_UP): 0:(215.19952,118.6725)
:Sending Trackball (ACTION_MOVE): 0:(-4.0,0.0)
:Sending Touch (ACTION_DOWN): 0:(382.0,594.0)
:Sending Touch (ACTION_UP): 0:(390.3301,591.6351)
:Sending Touch (ACTION_DOWN): 0:(2068.0,144.0)
:Sending Touch (ACTION_UP): 0:(2066.68,192.00432)
:Sending Touch (ACTION_DOWN): 0:(1207.0,311.0)
:Sending Touch (ACTION_UP): 0:(1240.4933,320.63553)
:Sending Trackball (ACTION_MOVE): 0:(2.0,0.0)
// 启动App 事件
2.7.3 异常信息
//若当 Monkey 执行过程中遇到错误时,就会输出对应异常信息。例如:
// CRASH: com.tencent.android.qqdownloader (pid 912)
// 发送Crash 的应用包名和pid

// Short Msg: java.lang.ClassNotFoundException
//Crash 的简要信息

// Long Msg: java.lang.ClassNotFoundException: Didn't find class "com.qq.AppService.AstApp" on path DexPathList[[zip file "/data/app/com.tencent.android.qqdownloader-2.apk"],nativeLibraryDirectories[/data/app-lib/com.tencent.android.qqdownloader-2, /vendor/lib, /system/lib]]
//Crash 的详细信息

// Build Label: Xiaomi/pisces/pisces:4.4.4/KTU84P/5.12.24:user/release-keys
// Build Changelist: 5.12.24
// Build Time: 1450958964000
// 机型和系统信息

// java.lang.RuntimeException: Unable to instantiate application com.qq.AppService.AstApp: java.lan.ClassNotFoundException: Didn't find class "com.qq.AppService.AstApp" on path: DexPathList[[zip fil "/data/app/com.tencent.android.qqdownloader-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.
tecent.android.qqdownloader-2, /vendor/lib, /system/lib]]
// at android.app.LoadedApk.makeApplication(LoadedApk.java:509)
// at android.app.ActivityThread.access$1500(ActivityThread.java:138)
// at dalvik.system.NativeStart.main(Native Method)
// ... 11 more
//Crash 的详细日志
2.7.4 执行结果(正常)
Events injected: 100
// 执行的事件数量

:Sending rotation degree=0, persist=false
// 旋转的角度为0

:Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0
// 丢失的事件数量

## Network stats: elapsed time=227ms (0ms mobile, 0ms wifi, 227ms not connected)
// 网络状态,移动网络联网0ms ,Wi-Fi 联网0ms ,没联网227ms

// Monkey finished

2.7.5 执行结果(异常)
** Monkey aborted due to error.
Monkey 执行失败
Events injected: 8
// 执行的事件数量

:Sending rotation degree=0, persist=false
// 旋转的角度为0

:Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0
// 丢失的事件数量

## Network stats: elapsed time=405ms (0ms mobile, 0ms wifi, 405ms not connected)
// 网络状态

** System appears to have crashed at event 8 of 100 using seed 1454216848235
// 提示在执行到第8 个事件时出现Crash ,以及所使用的随机种子seed的值
2.7.6 文本日志内容异常分析搜索

在文本内点击Ctrl+F查找功能,查找一些异常关键字。例:

程序无响应,ANR问题:在日志中搜索“ANR”;

ANR 是指当 Android 系统监测到应用程序在 5 秒内没有响应输入的事件或广播在 10 秒内没有执行完毕时抛出的无响应提示。

崩溃问题:在日志中搜索“CRASH”;

Crash 是指当应用程序出现错误时导致程序异常停止或退出的情况

其他问题:在日志中搜索”Exception”;


到此!我们的压力测试就已经结束啦!相信大家认真看完,对使用adb Monkey的一个压力测试也已经有或多或少的理解了,我在后会附上可能安卓会发生的无法进入ADB的几种情况处理和对应的处理方式!希望大家好好学习!天天向上噢~

三、 ADB无法进入情况及处理方法

3.1 错误提示:error: more than one device/emlator
解决1:
taskkill /f /im adb.exe
//此错误提示出现大多数情况为adb连接端口过多或被占用,再或者由于连接adb时间过长未操作导致的错误
//可通过上方命令行关闭进程而得到解决,再不济请重启电脑噢

解决2:
tasklist
//查询进程号
taskkill/f /pid pid号码
//关闭进程
3.2 错误提示:error: unknown host service
//运行Monkey请关闭杀毒软件,有时候360会莫名占用端口
netstat -ano | findstr "5037" 
//查询5037占用的pid号
taskkill/f /pid pid号码
//后使用命令行关闭进程即可
3.3 错误提示:*daemon not running.starting it now on port 5037*
缺少adb的程序文件
taskkill /f /im adb.exe
使用命令行关闭adb,重新进入或重启都可以解决
3.4 错误提示:error: no devices/emulators found
未连接数据线,或者你得数据线坏了,重新拔出插入或者换一个接口或换一条线
若提示无法识别Usb设备,则重新安装adb更新驱动或重新启动

Guess you like

Origin blog.csdn.net/Carp712/article/details/128904894
Recommended