Monkey日志分析是Monkey测试中非常重要的一个环节, 通过日志分析, 可以获取当前测试对象在测试过程中是否会发生异常, 以及发生的概率, 同时还可以获取对应的错误信息, 帮助开发定位和解决问题。 介绍日志分析方法之前, 先来看一下日志的保存方法。
1.Monkey日志的保存方法
Monkey运行日志常见的保存方法有三种:
·保存在PC中, 代码如下:
adb shell monkey [option] >d:\monkey.txt
执行以上命令, Monkey的运行日志将被保存在PC上的D盘下的一个monkey.txt文件中。
·保存在手机中, 代码如下:
adb shell
monkey [option] < count> > /mnt/sdcard/monkey.txt
执行以上命令, Monkey的运行日志将被保存在手机中的SD卡上的一个monkey.txt文件中。
·标注流与错误流分开保存, 代码如下:
Monkey [option] < count> 1>/sdcard/monkey.txt 2>/sdcard/error.txt
执行以上命令, Monkey的运行日志和异常日志将被分开保存。 此时Monkey的运行日志将被保存在monkey.txt文件中, 而异常日志将被保存在D盘下的error.txt中。
执行结束后, 可以看到SD卡上新增加了monkey.txt和error.txt。 monkey.txt显示运行日志
如果Monkey执行期间存在Crash(崩溃) 或ANR(Application Not Responding, 应用程序无响应) , error.txt中会显示错误日志。
2.Monkey日志内容解析
Monkey运行时输出的日志一般包含四类信息, 分别是测试命令信息、 伪随机事件流信息、 异常信息、 Monkey执行结果信息。
1) 测试命令信息
Monkey启动后会输出当前所执行命令的各种参数信息, 其中包括种子(Seed) 信息、 事件数量、 可运行的应用列表以及各事件百分比等。 这些信息都是通过Monkey命令参数所指定的, 这部分日志信息的解析, 如代码所示。
//测试命令信息
//随机种子值, 执行事件数量
:Monkey: seed=1454215444564 count=10
//可运行的应用列表
:AllowPackage: com.tencent.android.qqdownloader
//Category包含
LAUNCHER和
MONKEY
:IncludeCategory: android.intent.category.LAUNCHER
:IncludeCategory: android.intent.category.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
// 8: 2.0% 事件
8:
–pct-appswitch
// 9: 1.0% 事件
9:
–pct-flip
// 10: 13.0% 事件
10:
–pct-anyevent
2) 伪随机事件流信息
当Monkey开始执行测试后, 会顺序输出执行的事件流信息, 主要是前面提到的11大事件。 这部分日志信息的解析;
//执行的事件流信息
//启动
App事件
:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.tencent.android.qqdownloader/com.tencent.assistant.activity.SplashActivity;end
// Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.tencent.android.qqdownloader/com.tencent.assistant.activity.SplashActivity } in packagecom.tencent.android.qqdownloader
//轨迹球事件
:Sending Trackball (ACTION_MOVE): 0:(4.0,2.0)
//点击事件
:Sending Touch (ACTION_DOWN): 0:(387.0,1858.0)
:Sending Touch (ACTION_UP): 0:(385.8215,1861.3011)
//延时
Sleeping for 0 milliseconds…
3) 异常信息
当Monkey执行过程中遇到错误时, 会输出对应异常信息, 如代码清单所示。
//发送
Crash的应用包名和
pid
// CRASH: com.tencent.android.qqdownloader (pid 912)
//Crash的简要信息
// 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]]
//机型和系统信息
// Build Label: Xiaomi/pisces/pisces:4.4.4/KTU84P/5.12.24:user/release-keys
// Build Changelist: 5.12.24
// Build Time: 1450958964000
//Crash的详细日志
// 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
//
4) Monkey执行结果信息
当Monkey执行完所有事件后, 会输出执行结果信息, 其中包括执行的事件数量、 旋转的角度、 丢失的事件数量、 网络状态以及Monkey最终的执行结果, 如代码清单所示。
//执行的事件数量
Events injected: 10
//旋转的角度为
0:
Sending rotation degree=0, persist=false
//丢失的事件数量
:Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0
//网络状态, 移动网络联网
0ms,
Wi-Fi联网
0ms, 没联网
144ms## Network stats: elapsed time=144ms (0ms mobile, 0ms wifi, 144ms not connected)
// Monkey finished
如果Monkey执行过程中出现了异常导致执行失败, 会输出对应的执行失败的原因, 第几个事件执行失败以及所使用的随机种子数, 如代码清单所示。
//显示
Monkey执行失败
** Monkey aborted due to error.
//执行的事件数量
Events injected: 8
//旋转的角度为
0:
Sending rotation degree=0, persist=false
//丢失的事件数量
:Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0
//网络状态## Network stats: elapsed time=405ms (0ms mobile, 0ms wifi, 405ms not connected)
//提示在执行到第
8个事件时出现
Crash, 以及所使用的随机种子的值
** System appears to have crashed at event 8 of 100 using seed 1454216848235
3.Monkey日志异常信息查找
Monkey执行过程中常见的错误类型主要有两类: 应用程序无响应(ANR) 和崩溃(Crash) 。
ANR是指当Android系统监测到应用程序在5秒内没有响应输入的事件或广播在10秒内没有执行完毕时抛出无响应提示。 当出现ANR时弹出的错误提示框如图所示。
Crash是指当应用程序出现错误时导致程序异常停止或退出的情况, 当出现Crash时通常会弹出对应的错误提示框如图所示。
要统计Monkey日志中错误出现的次数也非常简单, 只要搜索关键字“ANR”和“CRASH”出现的次数即可。 由于通常Monkey测试的日志会比较大, 日志内容也非常多, 为了简化统计操作, 可以使用bat脚本进行统计;
Monkey日志分析bat脚本
@echo off&setlocal enabledelayedexpansion
#设置所有
Monkey日志存放的目录
set ff=log\*.txt
#设置查询关键字
set str=CRASH crash ANR died
#设置查询结果存放的目录
set fileName=Result.txt
#开始查询
echo 正在统计
&echo;
echo %date% %time% >%fileName%
echo.>>%fileName%
echo 分析结果:
>>%fileName%
echo ---------------------------------------------->>%fileName%
#依次打开目录下每一个
Monkey日志查询关键字并输出个数
(for %%a in (%str%)do (
set n%%a=0&set/p= %%a : con
for /f "delims=" %%b in ('findstr "%%a" "%ff%"')do (
set h=%%b
call :yky %%a)
echo !n%%a!>con
echo 关键字
%%a 共有
!n%%a! 处
))>>%fileName%
echo.>>%fileName%
#针对崩溃的日志输出其所在文件行数
echo 崩溃日志:
>>%fileName%
findstr "%str%" "%ff%">>%fileName%
echo/&pause&exit
:yky
set/a n%1+=1
set h=!h:*%1=!
if defined h if not "!h:*%1=!"=="!h!" goto :yky
最终执行后, 在脚本目录下会生成Result.txt文件记录异常出现的次数
根据统计结果, 可以得到Crash和ANR出现的次数, 以及出现在哪个日志文件中, 出现该错误的包名。 如果需要更详细的错误信息, 可以打开对应的Monkey日志文件查询。 通过详细日志信息,测试可以定位到引起Crash的原因, 以及出现Crash的代码行信息。 这里给出常见的一些Crash错误信息;
当获取到Crash和ANR日志信息后, 理论上开发人员就可以开始根据日志内容分析和定位问题了。 但事实上, 要定位问题单靠日志信息还是非常困难的, 有时候开发人员还需要知道问题复现的场
景, 同时增加更多的调试日志以协助定位。 这时候, 他们可能会期望测试能够复现问题或者提供问题出现场景和操作步骤。 通常, 测试人员可以通过使用同一个种子数(seed值) , 再次执行Monkey
来尝试复现问题。 这种方法比较费时, 并且不是所有的随机Crash和ANR都可以通过这种方法来复现。 那问题来了, 在Monkey出现问题的时候有没有可能即时地截图并且记录下操作步骤呢? Monkey
本身是没有这个能力的, 但是通过一些Monkey改造可以实现该功能。 在4.4节会详细介绍Monkey改造的方法, 大家不妨带着这个问题继续往下看。