Android自动化测试之Monkey测试

如果开发完app,开发人员没有充分的自测,然后等到测试人员反馈bug的时候已经晚了,所以作为一个合格的程序猿,很有必要掌握测试技术,也就是自动化测试了,将bug摁死在开发阶段;我们总不能花一天在那用手点点点吧,不现实,想想你晚上下班,把自动化测试一开,放在办公室跑一晚上,第二天过来直接看结果,多嗨。

在说自动化测试之前,其实现在市面上有很多自动化测试平台,做的都很全面了,而且还提供了很多机型供你选择,比如:

* 腾讯优测云测试平台

* 华为开发者联盟

* Testin 云测

唯一一个缺点就是【收费】再见,本着为公司着想微笑还是我们自己动手吧。

现在通用的一些测试工具如下:

  1. Monkey:Android SDK自带的一个命令行工具,使用adb来运行它,向系统发送伪随机的用户事件流,如按键、触屏、输入等;实现对正在开发的应用程序进行压力测试,伴随着日志输出。实际上该工具只能做程序做一些压力测试,由于测试事件和数据都是随机的,不能自定义,所以有很大的局限性。
  2. MonkeyRunner:Android SDK提供的测试工具,位于tools目录下,比Monkey强大,可以编写脚本来自定义数据,事件;但是脚本是采用python语言编写的,其实就是对python进行了封装,对测试人员要求较高。
  3. Instrumentation:这个是Google早期提供的测试自动化测试工具类,可以看成是Android的一个组件,可以模拟用户众多事件,通常用来单元测试,对测试人员要求较高,需要了解Android的api。
  4. UiAutomator:Android提供的自动化测试框架,也是目前最佳的UI测试框架,基本上支持所有的用户事件,可以抓取APP页面控件属性,测试代码结构简单,编写容易,能跨APP测试,但是要求设备在Android4.1以上,不支持Hybird APP,WebApp。
  5. Appium:这应该是最近很火的一个测试框架,支持Native APP,Hybird APP,Web APP;可以跨平台在Windows,Mac,Linux使用,支持Android,ios;支持java,js,php,Python等语言编写测试脚本。

Monkey命令介绍

我们在cmd中先进入adb所在目录,然后输入命令 adb shell monkey -help 可以查看到monkey相关的命令


  1. -p 用于约束限制,用此参数指定一个包,指定包后Monkey将被允许启动指定应用;如果不指定包,  Monkey将被允许启动设备中的所有应用(主Activity有android.intent.category.LAUNCHER 或android.intent.category.MONKEY类别 )。比如 adb shell monkey -p xxx.xxx.xxx 1  ; xxx.xxx.xxx 表示应用包名,1 表示monkey模拟用户随机事件参数,最低1,这样就能把应用启动起来
  2. -v 用于指定反馈信息级别,也就是日志的详细程度,分三个;-v 默认值,仅提供启动提示,操作结果等少量信息 比如adb shell monkey -p  xxx.xxx.xxx -v 1 ;-v -v 提供比较详细信息,比如启动的每个activity信息 ,比如adb shell monkey -p xxx.xxx.xxx -v -v 1 ;-v -v -v 提供最详细的信息 ,比如adb shell monkey -p xxx.xxx.xxx -v -v -v 1 
  3. -s 伪随机数生成器的种子值,如果我们两次monkey测试事件使用相同的种子值,会产生相同的事件序列;如果不指定种子值,系统会产生一个随机值。种子值对我们复现bug很重要。使用如下adb shell monkey -p xxx.xxx.xxx -s 11111 10
  4. --ignore-crashes 忽略异常崩溃,如果不指定,那么在monkey测试的时候,应用发生崩溃时就会停止运行;如果加上了这个参数,monkey就会运行到指定事件数才停止。比如adb shell monkey -p xxx.xxx.xxx -v -v -v  --ignore-crashes 10 
  5. --ignore-timeouts 忽略ANR,情况与4类似,当发送ANR时候,让monkey继续运行。比如adb shell monkey -p xxx.xxx.xxx -v -v -v  --ignore-timeouts 10
  6. --ignore-native-crashes 忽略native层代码的崩溃,情况与4类似,比如adb shell monkey -p xxx.xxx.xxx -v -v -v  --ignore-native-crashes 10
  7. --ignore-security-exceptions 忽略一些许可错误,比如证书许可,网络许可,adb shell monkey -p xxx.xxx.xxx -v -v -v  --ignore-security-exceptions 10
  8. --monitor-native-crashes 是否监视并报告native层发送的崩溃代码,adb shell monkey -p xxx.xxx.xxx -v -v -v  --monitor-native-crashes 10
  9. --kill-procress-after-error 用于在发送错误后杀死进程
  10. --hprof  设置后,在Monkey事件序列之前和之后立即生产分析报告,保存于data/mic目录,不过将会生成大量几兆文件,谨慎使用
  11. --throttle 设置每个事件结束后延迟多少时间再继续下一个事件,降低cpu压力;如果不设置,事件与事件之间将不会延迟,事件将会尽快生成;一般设置300ms,因为人最快300ms左右一个动作,比如 adb shell monkey -p xxx.xxx.xxx -v -v -v  --throttle 300 10
  12. --pct-touch 设置触摸事件的百分比,即手指对屏幕进行点击抬起(down-up)的动作;不做设置情况下系统将随机分配各种事件的百分比。比如adb shell monkey -p xxx.xxxx.xxx --pct-touch 50 -v -v 100 ,这就表示100次事件里有50%事件是触摸事件
  13. --pct-motion 设置运动事件百分比,这种事件类型是由屏幕上某处的一个down事件-一系列伪随机的移动事件-一个up事件,即点击屏幕,然后直线运动,最后抬起这种运动。
  14. --pct-trackball 设置轨迹球事件百分比,这种事件类型是一个或者多个随机移动,包含点击事件;这里可以是曲线运动
  15. --pct-syskeys 设置系统按键事件百分比,比如home键,音量键,返回键,拨打电话等
  16. --pct-nav 设置基本的导航按键事件百分比,比如输入设备上的上下左右四个方向键
  17. --pct-appswitch 设置activity跳转事件的百分比
  18. --ptc-anyevent 设置其它事件百分比
  19. --ptc-majornav 设置主导航事件的百分比
  20. 保存dos窗口打印的monkey信息,在monkey命令后面补上输出地址,如adb shell monkey -p xxx.xxxx.xxx  -v -v 100 > D:\monkey.txt;这样monkey测试结束后,所有打印的信息都会输出到这个文件里
  21. 通过adb bugreport 命令可以获取整个android系统在运行过程中所有app的内存使用情况,cpu使用情况,activity运行信息等,包括出现异常等信息。使用方法 adb bugreport > bugreport.txt ;这样在当前目录就会产生一个txt文件和一个压缩包,具体信息可在压缩包查看,txt文件只会记录压缩包的生成过程信息
  22. -f 加载monkey脚本文件进行测试,比如 adb shell monkey -f sdcard/monkey.txt -v -v 500

Monkey使用

1.进入adb目录

2.通过adb install apk名字

3.输入adb shell monkey -p xxx.xxxx.xxx  -s 123123 --throttle 300 -v -v 20 > d:\monkey.txt,这里指定了seed值,每个事件之间休息300ms,执行了20个事件,然后将日志信息保存在了monkey.txt文件中

4.打开文件,查看信息如下

:Monkey: seed=123123 count=20 //seed值是指定的123123,方便出现bug后再复现 事件次数是20
:AllowPackage: com.android.mangodialog // 应用包名
:IncludeCategory: android.intent.category.LAUNCHER //启动的主activity的类别,两种只要有一种就行
:IncludeCategory: android.intent.category.MONKEY
// Selecting main activities from category android.intent.category.LAUNCHER
//   + Using main activity com.android.mangodialog.MainActivity (from package com.android.mangodialog) //该应用符合这种类别的activity
// Selecting main activities from category android.intent.category.MONKEY
// Seeded: 123123
// Event percentages://各种事件的百分比
//   0: 15.0%  //可通过--pct-touch 参数设置的事件的百分比 常用
//   1: 10.0%  //可通过--pct-motion 参数设置的事件的百分比 常用
//   2: 2.0%   //可通过--pct-pinchzoom 参数设置的事件的百分比
//   3: 15.0%  //可通过--pct-trackball 参数设置的事件的百分比
//   4: -0.0%  
//   5: -0.0%  
//   6: 25.0%  //可通过--pct-nav 参数设置的事件的百分比
//   7: 15.0%  //可通过--pct-majornav 参数设置的事件的百分比
//   8: 2.0%   //可通过--pct-syskeys 参数设置的事件的百分比 常用
//   9: 2.0%   //可通过--pct-appswitch 参数设置的事件的百分比 常用
//   10: 1.0%  //可通过--pct-flip 参数设置的事件的百分比
//   11: 13.0% //可通过--pct-anyevent 参数设置的事件的百分比 
//启动的activity
:Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.mangodialog/.MainActivity;end
    // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.android.mangodialog/.MainActivity } in package com.android.mangodialog
Sleeping for 300 milliseconds //设置的事件之间间隔300ms 下面就是执行点击事件
:Sending Key (ACTION_DOWN): 82    // KEYCODE_MENU
:Sending Key (ACTION_UP): 82    // KEYCODE_MENU
Sleeping for 300 milliseconds
:Sending Key (ACTION_DOWN): 23    // KEYCODE_DPAD_CENTER
:Sending Key (ACTION_UP): 23    // KEYCODE_DPAD_CENTER
Sleeping for 300 milliseconds
    // Allowing start of Intent { cmp=com.android.mangodialog/.MainActivity2 } in package com.android.mangodialog
:Sending Key (ACTION_DOWN): 22    // KEYCODE_DPAD_RIGHT
:Sending Key (ACTION_UP): 22    // KEYCODE_DPAD_RIGHT
Sleeping for 300 milliseconds
:Sending Key (ACTION_DOWN): 21    // KEYCODE_DPAD_LEFT
:Sending Key (ACTION_UP): 21    // KEYCODE_DPAD_LEFT
Sleeping for 300 milliseconds
:Sending Touch (ACTION_DOWN): 0:(1017.0,280.0)
:Sending Touch (ACTION_UP): 0:(1021.8751,281.12732)
Sleeping for 300 milliseconds
:Sending Touch (ACTION_DOWN): 0:(1005.0,1599.0)
:Sending Touch (ACTION_UP): 0:(994.4962,1589.7715)
Sleeping for 300 milliseconds
:Sending Key (ACTION_DOWN): 2    // KEYCODE_SOFT_RIGHT
:Sending Key (ACTION_UP): 2    // KEYCODE_SOFT_RIGHT
Sleeping for 300 milliseconds
:Sending Key (ACTION_DOWN): 20    // KEYCODE_DPAD_DOWN
:Sending Key (ACTION_UP): 20    // KEYCODE_DPAD_DOWN
Sleeping for 300 milliseconds
:Sending Key (ACTION_DOWN): 22    // KEYCODE_DPAD_RIGHT
:Sending Key (ACTION_UP): 22    // KEYCODE_DPAD_RIGHT
Sleeping for 300 milliseconds //轨迹球运动
:Sending Trackball (ACTION_MOVE): 0:(4.0,-5.0)//手机屏幕上的坐标
Events injected: 20 //monkey共执行了20次事件
:Sending rotation degree=0, persist=false
:Dropped: keys=0 pointers=0 trackballs=0 flips=0 rotations=0
//测试过程中的网络状态,花费了3064ms连接,既没有连接上手机网络,也没有连接上wifi
## Network stats: elapsed time=3064ms (0ms mobile, 0ms wifi, 3064ms not connected) 

// Monkey finished //monkey测试结束

5.平时会使用比较复杂的参数去测试,如下

adb shell monkey -v -v -v -s 123123 --throttle 300 --pct-touch 40 --pct-motion 25 --pct-appswitch 25 --pct-syskeys 10 --pct-majornav 0 --pct-nav 0 --pct-trackball 0 --ignore-crashes --ignore-timeouts --ignore-native-crashes -p xxx.xxx.xxx 100000 > d:\monkey.txt

具体什么意思就不再一一解释了。

6.其实我们比较关注的是app在使用过程中出现的错误信息,像上面我们选择忽略掉集中错误情况,这样当monkey执行结束后,相关的信息会被写入到monkey文件中,但是错误信息比如crash,anr等信息会打印在dos窗口,这些错误信息会明确的指出哪里发生的错误;如果需要复现,我们可以把忽略参数去掉,然后通过相同的seed值再次进行monkey测试,直到发生错误跳出monkey测试,我们再查看,如下

public class MainActivity2 extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_main2);
        float s = 1/0;
    }
}

我这第二个activity的oncreate方法中写这个会报错的代码,然后在第一个activity的一个按钮中进行跳转进入这个activity,接下来进行monkey测试来复现这个bug

adb shell monkey -p xxx.xxx.xxx -s 123456 -v -v 2000  > d:\monkey.txt

我们看这个文件

.....................

:Sending Trackball (ACTION_MOVE): 0:(4.0,-3.0)
:Sending Trackball (ACTION_MOVE): 0:(-2.0,1.0)
:Sending Trackball (ACTION_DOWN): 0:(0.0,0.0)
:Sending Trackball (ACTION_UP): 0:(0.0,0.0)
Sleeping for 300 milliseconds
    // Allowing start of Intent { cmp=com.android.mangodialog/.MainActivity2 } in package com.android.mangodialog
** Monkey aborted due to error.

Events injected: 190

............................

这里可以看到是当打开MainActivity2的时候monkey发生错误退出,只执行了190个事件。至于错误信息打印在了dos窗口。

这里我们也可以通过adb bugreport命令将手机运行日志导出来查看,这里面的信息更详细,包括出错信息。


Monkey脚本

monkeyscript是monkey的脚本语言,能够被monkey识别的命令集合,可以实现一些固定的重复性动作。Monkey可以通过命令加载脚本来进行测试,简单方便。

脚本格式如下

type= raw events
count= 1
speed= 1.0   
start data >>   

LaunchActivity(pkg_name, cl_name)  

  1. 第一句到第三局就使用默认值,不需要改,其实这里设置是无效的,最终会采用命令行里的值;
  2. start data >> 表示开始执行下面所有的命令行
  3. LaunchActivity就是一个启动应用的命令

脚本命令

  1. LaunchActivity(pkg_name, cl_name) 打开应用,第一个参数是包名,第二个是启动的activity名
  2. DispatchPress(keyName) 按下物理按键,例如home键,back键;参数是按键值 ,按键值可查看keycode
  3. Tap(x, y) 点击屏幕,参数是点击坐标
  4. Drag(xStart, yStart, xEnd, yEnd) 滑动屏幕,坐标是从哪一点滑到哪一点
  5. LongPress() 长按2s
  6. ProfileWait 等待5s
  7. PressAndHold(x, y, pressDuration) 模拟长按 
  8. PinchZoom(x1Start, y1Start, x1End, y1End, x2Start, y2Start, x2End, y2End, stepCount) 模拟缩放
  9. DispatchString(input) 输入字符串
  10. RunCmd(cmd) 执行shell命令,比如截图 screencap -p /data/local/tmp/tmp.png
  11. RotateScreen(rotationDegree, persist) 选择屏幕,第一个参数是旋转角度,第二个是旋转后是否停在当前位置
  12. DispatchFlip(true/false) 打开或者关闭软键盘
  13. UserWait(sleepTime) 睡眠指定时间
  14. DeviceWakeUp() 唤醒屏幕
  15. DispatchPointer(downtime,eventTime,action,x,yxpressure,size,metastate,xPrecision,yPrecision,device,edgeFlags) 向指定位置发送单个手势
  16. 更多方法可查看Monkey源码

现在来写一个脚本:

type= raw events
count= 1
speed= 1.0   
start data >>   
LaunchActivity(com.android.mangodialog,com.android.mangodialog.MainActivity);
UserWait(1000);

Tab(500,300);
DispatchPress(KEYCODE_ENTER)
UserWait(1000);

DispatchPress(KEYCODE_BACK);
UserWait(1000);

RunCmd(screencap -p /sdcard/tmp.png);
UserWait(1000);

Drag(0, 0, 500, 500);
DispatchPress(KEYCODE_ENTER)
UserWait(1000);

DispatchString(www.baidu.com);
UserWait(1000);

DispatchPress(KEYCODE_BACK);

UserWait(1000);

然后通过adb push d:\monkey.txt sdcard/monkey.txt 将文件推送到手机sd卡上,然后通过

adb shell monkey -f sdcard/monkey.txt -v -v 1 执行脚本文件

猜你喜欢

转载自blog.csdn.net/qq_30993595/article/details/80748559