zoukankan      html  css  js  c++  java
  • Android Monkey压力测试

    一、Monkey简介:

    Monkey是Android中的一个命令行工具,可以运行在模拟器里或者现实设备中,向系统发送伪随机的用户事件流(点击、滑动、Application切换、横竖屏、应用关闭)实现对正在开发的应用程序进行压力测试。monkey测试是一种为了测试软件的稳定性,健壮性的快速有效的方法。只针对Activity做测试,不能对Service做测试。

    简单的理解:

    Monkey 是一个 Android 自动化测试小工具。主要用于Android 的压力测试, 主要目的就是为了测试app 是否会Crash.

    Monkey测试,就像一只猴子, 在电脑面前,乱敲键盘在测试。 猴子什么都不懂, 只知道乱敲。通过Monkey程序模拟用户触摸屏幕、滑动Trackball、 按键等操作来对设备上的程序进行压力测试,检测程序多久的时间会发生异常。

    二、质量要求:

    版本release(发布)前,Monkey跑出来的结果中crash要为0,final release前,Monkey跑完的总次数应为25W,结果里不允许有nullPointException出现。

    三、使用Monkey:

    在cmd命令或者AndroidStudio中的Terminal中都可以使用adb(注意adb的位置,在SDK的tools文件夹下)

      1、首先需要将手机连接到PC,测试连接是否正常,找到adb的位置,一般在sdk的tools文件下 ,找到位置然后输入adb devices来进行验证;

      2、因测试多针对一个特定的APP包,所以需要知道需要测试包的包名;可以直接问开发,也可以通过 adb shell pm list packages  列出所有包名来进行查找

      (不确定包是否已安装,可以用adb shell pm list packages [options] <INTENT> 来进行确认,它的含义是列举出所有包含<INTENT>的package。    e.g. adb shell pm list packages com.taobao.taobao)

      3、对特定APP包进行测试的命令为adb shell monkey -p <pakage.name>

    四、Monkey的基本参数:

    1、允许启动手机里面所有的 App , 随机操作 1000 次

     adb shell monkey 1000 

    2、-p : 允许启动 App 的包名

    • 启动一个包名的应用

    QQ 的包名为: com.tencent.mobileqq

     adb shell monkey -p com.tencent.mobileqq 1000 

    随机操作 手机 QQ 1000 次

    • 启动指定的多个 App

    微信的包名为:com.tencent.mm

     adb shell monkey -p com.tencent.mobileqq -p com.tencent.mm 1000 

    随机操作 手机 QQ 和 微信 1000 次

    3、-v : 操作日志记录

    命令行的每一个-v将增加反馈信息的级别。

    • -v:Level 0(缺省值)除 启动提示、测试完成和最终结果之外,提供较少信息。
    • -v -v :Level 1提供较为详细的测试信息,如逐个发送到Activity的 事件。
    • -v -v -v :Level 2提供更加详细的设置信息,如测试中被选中的或未被选中的Activity。

     adb shell monkey -p com.tencent.mobileqq -v -v -v 100 

    4、-s : 伪随机数生成器的seed值

    如果用相同的seed值再次运行monkey,将生成相同的事件序列。

     adb shell monkey -s 12345 -v 10 

    5、--ignore-crashes : 忽略操作是崩溃异常

    通常,应用发生崩溃或异常时Monkey会停止运行。如果设置此项,Monkey将继续发送事件给系统,直到事件计数完成。

     adb shell monkey --ignore-crashes -v 1000 

    6、--ignore-timeouts : 忽略超时

    通常,应用程序发生任何超时错误(如“Application Not responding”对话框)Monkey将停止运行,设置此项,Monkey将继续发送事件给系统,直到事件计数完成。

     adb shell monkey --ignore-timeouts -v 1000 

    7、--ignore-security-exceptions : 忽略程序发生许可异常

    通常,当程序发生许可错误(例如启动一些需要许可的Activity)导致的异常时,Monkey将停止运行。设置此项,Monkey将继续发送事件给系统,直到事件计数完成。

     adb shell monkey --ignore-security-exceptions -v 1000 

    8、--throttle : 插入固定延迟

    在事件之间插入固定延迟。通过这个选项可以减缓Monkey的执行速度。如果不指定该选项,Monkey将不会被延迟,事件将尽可能快地被执行。

     adb shell monkey --throttle 500 -v 500 

    随机执行 500 个事件,每个事件之间延迟 500 毫秒被执行。

    9、--help : 列出简单的用法

     adb shell monkey -help 

    五、将log日志文件保存到指定位置:

      android studio 的terminal 下执行命令并且将测试结果保存到指定文件下:


                 adb shell monkey -p 包名 -s 100 --ignore-crashes --ignore-timeouts  1000000 >C:UsersdingchaoDesktop estlog.txt

    六、日志分析:

    1)正常情况:顺利执行完成, 在log的最后, 会打印出当前执行事件的次数和所花费的时间; // Monkey finished 代表执行完成

    详细分析参考:

    http://blog.sina.com.cn/s/blog_44d19b500102vefp.html

    http://blog.csdn.net/huangyabin001/article/details/38442359


    2)异常情况:

     

    其中adb shell procrank 查询各进程内存使用情况;adb shell cat /proc/meminfo 查看当前的内存情况...

     

    Monkey 测试出现错误后,一般的分析步骤
    看Monkey的日志 (为了进一步分析问题的来源,可以找到Log中出现问题处的前一次Switch,随后根据Log主要是查看相关的Activity)
    1、程序无响应的问题:在日志中搜索 “ANR”

    可能原因:当前有耗时操作在UI线程指定,导致卡UI了;在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸);BroadcastReceiver在10秒内没有执行完毕

    2、崩溃问题:在日志中搜索 “Exception”   (如果出现空指针, NullPointerException)  肯定是有bug
    3、搜索"crash" 、"error"

     Monkey 执行中断, 在log最后也能看到当前执行次数;若以上步骤还不能定位问题,可以使用之前执行的monkey命令再执行一遍,注意seed值要一样



    可能出现Crash的场景

    1)图片放大缩小

    2)输入框无限输入各种类型字符

    3)快速操作

    4)和系统的交互等等



    什么时候会有Log文件的产生 ?
    Log的产生大家都知道 , 大家也都知道通过DDMS来看log , 但什么时候会产生log文件呢 ?一般在如下几种情况会产生log文件 。 
    1,程序异常退出 , uncaused exception
    2,程序强制关闭 ,Force Closed (简称FC)
    3,程序无响应 , Application No Response (简称ANR) , 顺便,一般主线程超过5秒么有处理就会ANR
    4,手动生成 。


    拿到一个日志文件,要分成多段来看 。 log文件很长,其中包含十几个小单元信息,但不要被吓到 ,事实上他主要由三大块儿组成 。

    1,系统基本信息 ,包括 内存,CPU ,进程队列 ,虚拟内存 , 垃圾回收等信息 。------ MEMORY INFO (/proc/meminfo) ------
    ------ CPU INFO (top -n 1 -d 1 -m 30 -t) ------
    ------ PROCRANK (procrank) ------
    ------ VIRTUAL MEMORY STATS (/proc/vmstat) ------
    ------ VMALLOC INFO (/proc/vmallocinfo) ------

    格式如下:
    ------ MEMORY INFO (/proc/meminfo) ------
    MemTotal:         347076 kB
    MemFree:           56408 kB
    Buffers:            7192 kB
    Cached:           104064 kB
    SwapCached:            0 kB
    Active:           192592 kB
    Inactive:          40548 kB
    Active(anon):     129040 kB
    Inactive(anon):     1104 kB
    Active(file):      63552 kB
    Inactive(file):    39444 kB
    Unevictable:        7112 kB
    Mlocked:               0 kB
    SwapTotal:             0 kB
    SwapFree:              0 kB
    Dirty:                44 kB
    Writeback:             0 kB
    AnonPages:        129028 kB
    Mapped:            73728 kB
    Shmem:              1148 kB
    Slab:              13072 kB
    SReclaimable:       4564 kB
    SUnreclaim:         8508 kB
    KernelStack:        3472 kB
    PageTables:        12172 kB
    NFS_Unstable:          0 kB
    Bounce:                0 kB
    WritebackTmp:          0 kB
    CommitLimit:      173536 kB
    Committed_AS:    7394524 kB
    VmallocTotal:     319488 kB
    VmallocUsed:       90752 kB
    VmallocChunk:     181252 kB


    2,时间信息 , 也是我们主要分析的信息 。
    ------ VMALLOC INFO (/proc/vmallocinfo) ------
    ------ EVENT INFO (/proc/vmallocinfo) ------

    格式如下:
    ------ SYSTEM LOG (logcat -b system -v time -d *:v) ------
    01-15 16:41:43.671 W/PackageManager( 2466): Unknown permission com.wsomacp.permission.PROVIDER in package com.android.mms
    01-15 16:41:43.671 I/ActivityManager( 2466): Force stopping package com.android.mms uid=10092
    01-15 16:41:43.675 I/UsageStats( 2466): Something wrong here, didn't expect com.sec.android.app.twlauncher to be paused
    01-15 16:41:44.108 I/ActivityManager( 2466): Start proc com.sec.android.widgetapp.infoalarm for service com.sec.android.widgetapp.infoalarm/.engine.DataService: pid=20634 uid=10005 gids={3003, 1015, 3002}
    01-15 16:41:44.175 W/ActivityManager( 2466): Activity pause timeout for HistoryRecord{48589868 com.sec.android.app.twlauncher/.Launcher}
    01-15 16:41:50.864 I/KeyInputQueue( 2466): Input event
    01-15 16:41:50.866 D/KeyInputQueue( 2466): screenCaptureKeyFlag setting 0
    01-15 16:41:50.882 I/PowerManagerService( 2466): Ulight 0->7|0
    01-15 16:41:50.882 I/PowerManagerService( 2466): Setting target 2: cur=0.0 target=70 delta=4.6666665 nominalCurrentValue=0
    01-15 16:41:50.882 I/PowerManagerService( 2466): Scheduling light animator!
    01-15 16:41:51.706 D/PowerManagerService( 2466): enableLightSensor true
    01-15 16:41:51.929 I/KeyInputQueue( 2466): Input event
    01-15 16:41:51.933 W/WindowManager( 2466): No focus window, dropping: KeyEvent{action=0 code=26 repeat=0 meta=0 scancode=26 mFlags=9}



    3,虚拟机信息 , 包括进程的,线程的跟踪信息,这是用来跟踪进程和线程具体点的好地方 。 
    ------ VM TRACES JUST NOW (/data/anr/traces.txt.bugreport: 2011-01-15 16:49:02) ------
    ------ VM TRACES AT LAST ANR (/data/anr/traces.txt: 2011-01-15 16:49:02) ------


    格式如下 :
    ----- pid 21161 at 2011-01-15 16:49:01 -----
    Cmd line: com.android.mms

    DALVIK THREADS:
    "main" prio=5 tid=1 NATIVE
      | group="main" sCount=1 dsCount=0 s=N obj=0x4001d8d0 self=0xccc8
      | sysTid=21161 nice=0 sched=0/0 cgrp=default handle=-1345017808
      | schedstat=( 4151552996 5342265329 10995 )
      at android.media.MediaPlayer._reset(Native Method)
      at android.media.MediaPlayer.reset(MediaPlayer.java:1218)
      at android.widget.VideoView.release(VideoView.java:499)
      at android.widget.VideoView.access$2100(VideoView.java:50)
      at android.widget.VideoView$6.surfaceDestroyed(VideoView.java:489)
      at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:572)
      at android.view.SurfaceView.updateWindow(SurfaceView.java:476)
      at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:206)
      at android.view.View.dispatchDetachedFromWindow(View.java:6082)
      at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1156)
      at android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:2296)
      at android.view.ViewGroup.removeAllViews(ViewGroup.java:2254)
      at com.android.mms.ui.SlideView.reset(SlideView.java:687)
      at com.android.mms.ui.SlideshowPresenter.presentSlide(SlideshowPresenter.java:189)
      at com.android.mms.ui.SlideshowPresenter$3.run(SlideshowPresenter.java:531)
      at android.os.Handler.handleCallback(Handler.java:587)
      at android.os.Handler.dispatchMessage(Handler.java:92)
      at android.os.Looper.loop(Looper.java:123)
      at android.app.ActivityThread.main(ActivityThread.java:4627)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:521)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
      at dalvik.system.NativeStart.main(Native Method)

    ---------------------------------------------------------------------------------------------------------------------------------------
    闲话少说, 我总结了观察log文件的基本步骤 。 1,如果是ANR问题 , 则搜索“ANR”关键词 。 快速定位到关键事件信息 。
    2,如果是ForceClosed 和其它异常退出信息,则搜索"Fatal" 关键词, 快速定位到关键事件信息 。
    3,定位到关键事件信息后 , 如果信息不够明确的,再去搜索应用程序包的虚拟机信息 ,查看具体的进程和线程跟踪的日志,来定位到代码 。 

    用这种方法,出现问题,根本不需要断点调试 , 直接定位到问题,屡试不爽 。 
    下面,我们就开始来分析这个例子的log 。

    打开log文件 , 由于是ANR错误,因此搜索"ANR " , 为何要加空格呢,你加上和去掉比较一下就知道了 。 可以屏蔽掉不少保存到anr.log文件的无效信息 。

    关闭Monkey

    在monkey运行中,断开USB连接,mokey仍可继续运行
    1. ps命令查找进程
    adb shell ps | grep monkey  返回来的第一个数字,即是monkey的进程号
    2.kill 命令结束进程
    adb shell kill [刚才查到的进程号]

    测试之路,慢慢其修远兮
  • 相关阅读:
    GO开发[一]:golang语言初探
    Python带参数的装饰器
    Python函数篇
    19. logging模块
    18. json模块
    17. os模块
    16. sys模块
    15. random模块
    14. 模块-time模块
    29. java面向对象项目
  • 原文地址:https://www.cnblogs.com/zhengyao9236/p/11555871.html
Copyright © 2011-2022 走看看