monkey:
一:需覆盖的测试场景:
1、需覆盖机型:oppo vivo 华为 小米(这是宝玩app的用户量前4名的手机品牌,且这4家的手机系统都是基于安卓系统来深度定制开发的,差异较大,也是市场主流的4大安卓操作系统。)
2、根据需要填充memory到80%(考虑到有些用户的手机运行内存较小,有的手机运存一共才有1g或2g,实际可用的内存只有很少一部分,所以测试时将手机运存填充到80%,这样更能模拟用户的使用场景,也更容易发现一些因为内存不足导致的bug。)
3、覆盖android系统:4、5、6、7(目前主流的安卓系统,也是宝玩app支持兼容的安卓版本。)
4、发送事件的间隔时间最小达到360毫秒即可(1000毫秒=1秒,此间隔大约是每秒内发送3次随机事件,该时间是模拟了普通用户使用app的最快速度。)
5、每种机型发送事件次数不低于500000次,若没有异常抛出,则通过测试。(一般选择在晚上测试,可以几台测试机同时跑)
二:必须覆盖的事件类型(根据宝玩app的平台特性,总结出以下6种必须覆盖的事件类型,这6种事件类型都是用户使用app时可能出现的。):
1、触摸事件(触摸事件是一个down-up事件,它发生在屏幕的某单一位置)
2、动作事件(由屏幕上某处的一个donw事件、一系列的伪随机事件和一个up事件组成)
3、屏幕旋转事件(横屏和竖屏)
4、主要导航事件(这些导航事件通常引发图形界面的动作,如5-way键盘的中间按键、回退键、菜单键)
5、系统导航事件(这些按键通常都被保留,由系统使用,如home、back、start call、end call、音量键)
6、启动Activity事件(在随机时间里,通过startActivity方法最大限度的开启该package下的 全部Activity的一种方法)
三:必须解决的bug类型:
1、Exception异常的bug:如(内存溢出、数据异常、类不存在、类型转换出错、数学运算异常、方法参数异常、文件未找到、数值转换异常)
2、anr异常:如(空指针、超时、线程占用)
3、应用程序发生许可错误:如(证书许可、网络许可)
四:以下错误根据实际情况可以不解决:
1、手机系统本地代码造成的bug,且不影响用户使用。
2、非java层的错误,android底层代码出现的bug(如调用c语言的一些库),且不影响用户使用
六、Monkey分析报告
1.在日志中搜索关键字:
1)搜索报告中的关键字“ANR”,看有无应用无响应的事件(Application Not Responding)
2)搜索报告中的关键字“crash”,看有无崩溃的事件
3)搜索报告中的关键字“exception”,看有无其他异常事件。(如果出现空指针NullPointerException,需格外重视)下面的属于monkey自己的问题。不用管。
4)内存泄露问题搜索"GC"(需进一步分析)
2. 初步分析法: monkey出现错误后,一般的分析步骤
1)先找到出现错误的位置
2)查看出现错误之前2个switch之间的activity
3)手动执行事件,复现问题
4)若以上步骤还不能找出,产生错误时,有会seed值,输入相同的seed值,重新按照之前命令跑monkey
3.详细分析法:
1) ANR问题:在日志中搜索“ANR”(“Application Not Responding"),说明有bug,出现ANR,一般是主线程的响应超过5秒,或者BroadcastReceiver没有在10秒内作出响应。这个就是一个比较严重的缺陷。把耗时的操作另起线程来处理就可以了。
2)分析log中的具体信息:查看log中第一个Switch,主要是查看Monkey执行的是哪一个Activity,譬如下面的log中,执行的是com.tencent.smtt.SplashActivity,在下一个swtich之间的,如果出现了崩溃或其他异常,可以在该Activity中查找问题的所在。
3)内存泄漏
1) 内存泄漏弹出out of memory对话框
2)对于有内存泄漏但是没有单出out of memory对话框的情况,可以通过logcat文件GC出信息,(GC:java的垃圾回收机制)
GC_FOR_ALLOC: 因为在分配内存时候内存不够引起的
GC_EXPLICIT 表明GC被显式请求触发的,如System.gc调用,
GC_CONCCURRENT: 表明GC在内存使用率达到一定的警戒值时候,自动触发
GC_BEFORE_OOM 表明在虚拟机抛出内存不够异常oom之前,执行最后一次回收内存垃圾
3)发现内存泄露–内存报告分析(利用hprof参数的内存快照生成内存报告)在发现内存泄露后,可以执行相同的monkey,只需多加一个参数–hprof
adb shell monkey -p 包名 --hprof --throttle 100 --pct-touch 50 --pct-motion 50 -v -v -v 1000 >c:\monkey.txt
说明:如果指定了这个选项,monkey会在发送时间的前后生成APP内存快照文件,一般会在手机设备的/data/misc目录下生成hprof的文件。(注:/data/misc需要root权限,可以在手机上安装个RE查看或通过手机助手查看)
ps:文件转换:配置monkey测试时的sdk-tools下查看是否hprof-conv命令,在命令行输入hprof-conv -help得知文件转化用法,直接转化就行,由.hprof转化成.conv格式。
转化后的文件用eclipse的Memory Analyzer tool(MAT)查看(此插件可以下载),可以点击 Reports->Leak Suspects链接来生成报告。
最近看到了一个开源的测试monkey的github项目,具体使用和优点就不说了,大家可以访问链接https://github.com/zhangzhao4444/Maxim查看.
报告如下:
[Maxim] // Events injected: 51441
[Maxim] // Monkey is over!
[Maxim] // Sending rotation degree= 0, false
[Maxim] // Unaccounted for: 7200246
[Maxim] // Tested activities 7
[Maxim] // Activity of Coverage: 12.903225
[Maxim] // How many Events Dropped: keys=0, pointers=484, trackballs=0, flips=134, rotations=0
[Maxim] // ## Network stats: elapsed time= 7200246 ms ( 0 ms mobile, 0 ms wifi, 7200246 ms not connected )
[Maxim] // App appears 1 crash, 0 anr, monkey using seed 1573962064064!!!
[Maxim] // Monkey finished
android存异常日志的地方:
/data/system/dropbox
/data/dontpanic
/err
/data/tomstone
data/anr/trace.txt
data/anr/info.txt
dump&logcat
monkey crash 有6种
FC ANR 属于应用层面的crash
WatchDog 属于系统层面的
tombstone native层,一般是由Dalvik错误、状态监视调试器、C层代码以及libc的一些问题导致的。
modem 属于cp层
Kernel panics 属于内核层
前面2种是最常见的
tombstone 分为2种 一种为应用错误 一种为系统错误 需要具体定位分析
Android WatchDog主要作用:
1)接收系统内部reboot请求,重启系统。
2)监护SystemServer进程,防止系统死锁。
monkey测试除了以上几个文件夹需要拷贝
其实还有一个monkeyscreenlog
以及dumpsys.log
还有一个bugreport
这些也需要拷贝出来分析的
FC和ANR的错误可以直接看/data/system/dropbox里面的文件 有对应的关键字 例如 anr
dropbox里面event_data 就只有 start= XXXXX end=XXXXX
ANR发生的条件:
1.只有主线程才会产生ANR,主线程就是UI线程;
InputDispatching Timeout:5秒内无法响应屏幕触摸事件或键盘输入事件
BroadcastQueue Timeout :在执行前台广播(BroadcastReceiver)的onReceive()函数时10秒没有处理完成,后台为60秒。
Service Timeout :前台服务20秒内,后台服务在200秒内没有执行完毕。
ContentProvider Timeout :ContentProvider的publish在10s内没进行完。作者:Marker_Sky链接:https://www.jianshu.com/p/388166988cef来源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
APP出现ANR的原因:(这个是无反应)
1、主线程阻塞或者耗时操作
主线程执行了耗时操作,比如数据库操作或网络编程.
调用thread的join()方法、sleep()方法、wait()方法或者等待线程锁的时候.
其他线程持有锁,导致主线程等待超时.
其它线程终止或崩溃导致主线程一直等待
2、内存不足
优化内存使用.
定位到 logcat.log 文件中 "not responding" 发生时间点;去查看发生 ANR 时间点对应的 trace 文件,定位到应用报名,若Dalvik Thread主线程显示“SUSPENDED”,则为内存问题。
截取 ANR 发生时间点前 5s 的 log,分析 "dalvikvm" 打印的 Paused GC 耗时,如果过多则定位为 GC 问题,需要查看这 5s 件发生了哪些耗时的操作。
注意:发生 GC 的进程 id 需要和当前发生 ANR 的线程 id 的要一致
3、CPU满负荷,I/O阻塞
其他进程(就是其他程序)占用CPU导致本进程得不到CPU时间片,比如其他进程的频繁读写操作可能会导致这个问题。
借助于一些工具来进行检测,严格模式StrictMode是Android SDK提供的一个用来检测代码中是否存在违规操作的工具类,StrictMode主要检测两大类问题:
· 线程策略ThreadPolicy
- detectCustomSlowCalls: 检测自定义耗时操作。
- detectDiskReads: 检测是否存在磁盘读取操作。
- detectDiskWrites: 检测是否存在磁盘写入操作。
- detectNetwork: 检测是否存在网络操作。
· 虚拟机策略VmPolicy
- detectActivityLeaks: 检测是否存在Activity泄漏。
- detectLeakedClosableObjects: 检测是否存在未关闭的Closeable对象泄漏。
- detectLeakedSqlLiteObjects: 检测是否存在Sqlite对象泄漏。
- setClassInstanceLimit: 检测类实例个数是否超过限制。
示例:
ANR in com.demo.hybrid--Broadcast of Intent
MessageQueue.next->MessageQueue.nativePollOnce
Binder:c.a->ContentResolver.query->ApplicationContentResolver.acquireUnstableProvider->ActivityThread.acquireProvider->ActivityManagerProxy.getContentProvider
APP出现CRASH的原因:(其实就是闪退、FC)
1、程序异常:空值指针,数组越界、堆栈溢出、并发操作、逻辑错误.
2、内存不足app
所需的内存超过设备的限制,app跑不起来导致App crash.或是内存泄露,程序运行的时间越长,所占用的内存越大,最终用尽全部内存,导致整个系统崩溃。亦或非授权的内存位置的使用也可能会导致App crash。
3、CPU满负荷
示例:
java_exp:
java.lang.NullPointerException--Attempt to invoke virtual method 'android.content.res.Configuration android.content.res.Resources.getConfiguration()' on a null object reference
java.lang.IllegalStateException--Application not created
java.lang.IllegalArgumentException--Missing android.support.FILE_PROVIDER_PATHS meta-data
native_exp :
/system/lib64/libart.so (art_quick_alloc_object_initialized_region_tlab+40) /system/framework/arm64/boot-core-oj.oat (offset 0x2dc000) (java.nio.ByteBuffer.wrap+68)
Abort message: 'Check failed: key_value != nullptr compiler-filter not found in oat header'