Android自动化测试工具——Monkey
来源:互联网 发布:arctime字幕软件破解 编辑:程序博客网 时间:2024/06/07 05:16
Android自动化测试工具——Monkey
上一周的软件测试课刚刚练习过移动应用的测试,通过Android SDK中的uiautomatorviewer(一个由Android提供的、用来扫描和分析Android应用程序的UI组件的GUI工具)来获取界面中的一个元素,然后通过点击按钮,读取、修改文本等来模拟真实用户和应用之间的交互。今天来说说另一个工界和学界中常用的Android测试工具——Monkey
Monkey简介
Monkey测试是Android平台下自动化测试的一种快速有效的手段,可运行在模拟器和实体设备上。通过Monkey工具可以模拟用户触摸屏幕、滑动轨迹球、按键等操作来对模拟器或者手机设备上的软件进行压力测试,检测该软件的稳定性、健壮性。它的原理是向系统发送伪随机的用户事件流(如按键输入、触摸输入、手势输入等),实现对正在开发的应用程序进行压力测试。因为这个工具在App中乱按、乱摸、乱滚、乱跳,像一个调皮的猴子,所以被称为Monkey。
Monkey工具的特点
- 1.测试对象为程序包,有一定局限性
- 2.使用的事件流数据流是随机的,不能自定义
- 3.可对事件数量、类型、频率设置
补充:MonkeyRunner官方文档的网址
http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html
Monkey的基本语法
(!!!注:这里由于博客编辑器的原因,“-s ”的参数seed前面加了一个“\”,正常情况下没有这个符号。)
Monkey测试示例图解
我选择的app是开源中国(上周测试考试用到的apk)
(1)将apk安装到模拟器中。安装后,能够在模拟器中看到安装好的apk,如下图:
(2)安装好apk文件后,需要知道应用程序主Activity(第一个启动的Activity)所在的包名。
获取包名有多种方法,可以参照这个网址中提到的指令。
http://www.51testing.com/html/93/136593-3714533.html
这里得到的包名如下图:
(3) 使用moneky命令进行自动化压力测试。
命令为:
#monkey -p net.oschina.app.improve -v 100//(参数说明:-p后跟软件所在包名,-v后跟测试的次数)。这里对该软件发送了100次的伪随机事件,即进行了100次的自动化测试。
(4) 查看测试的结果。
我的测试结果如下图:
如果测试没有通过,会报错。如果输出了“Monkey Finished”则说明测试通过,这里的测试通过。
但是查看结果还是有不明白的地方,如Event Percentages的0-10各代表什么?
这一点,我们可以查看android-4.2.2_r1.2中的MonkeySourceRandom.java中定义的这些值:
public static final int FACTOR_TOUCH = 0; public static final int FACTOR_MOTION = 1; public static final int FACTOR_PINCHZOOM = 2; public static final int FACTOR_TRACKBALL = 3; public static final int FACTOR_ROTATION = 4; public static final int FACTOR_NAV = 5; public static final int FACTOR_MAJORNAV = 6; public static final int FACTOR_SYSOPS = 7; public static final int FACTOR_APPSWITCH = 8; public static final int FACTOR_FLIP = 9; public static final int FACTOR_ANYTHING = 10; public static final int FACTORZ_COUNT = 11; // should be last+1 private static final int GESTURE_TAP = 0; private static final int GESTURE_DRAG = 1; private static final int GESTURE_PINCH_OR_ZOOM = 2;
然后再来看Monkey.java源码中的processOptions()方法
private boolean processOptions() { // quick (throwaway) check for unadorned command if (mArgs.length < 1) { showUsage(); return false; } try { String opt; while ((opt = nextOption()) != null) { if (opt.equals("-s")) { mSeed = nextOptionLong("Seed"); } else if (opt.equals("-p")) { mValidPackages.add(nextOptionData()); } else if (opt.equals("-c")) { mMainCategories.add(nextOptionData()); } else if (opt.equals("-v")) { mVerbose += 1; } else if (opt.equals("--ignore-crashes")) { mIgnoreCrashes = true; } else if (opt.equals("--ignore-timeouts")) { mIgnoreTimeouts = true; } else if (opt.equals("--ignore-security-exceptions")) { mIgnoreSecurityExceptions = true; } else if (opt.equals("--monitor-native-crashes")) { mMonitorNativeCrashes = true; } else if (opt.equals("--ignore-native-crashes")) { mIgnoreNativeCrashes = true; } else if (opt.equals("--kill-process-after-error")) { mKillProcessAfterError = true; } else if (opt.equals("--hprof")) { mGenerateHprof = true; } else if (opt.equals("--pct-touch")) { int i = MonkeySourceRandom.FACTOR_TOUCH; mFactors[i] = -nextOptionLong("touch events percentage"); } else if (opt.equals("--pct-motion")) { int i = MonkeySourceRandom.FACTOR_MOTION; mFactors[i] = -nextOptionLong("motion events percentage"); } else if (opt.equals("--pct-trackball")) { int i = MonkeySourceRandom.FACTOR_TRACKBALL; mFactors[i] = -nextOptionLong("trackball events percentage"); } else if (opt.equals("--pct-rotation")) { int i = MonkeySourceRandom.FACTOR_ROTATION; mFactors[i] = -nextOptionLong("screen rotation events percentage"); } else if (opt.equals("--pct-syskeys")) { int i = MonkeySourceRandom.FACTOR_SYSOPS; mFactors[i] = -nextOptionLong("system (key) operations percentage"); } else if (opt.equals("--pct-nav")) { int i = MonkeySourceRandom.FACTOR_NAV; mFactors[i] = -nextOptionLong("nav events percentage"); } else if (opt.equals("--pct-majornav")) { int i = MonkeySourceRandom.FACTOR_MAJORNAV; mFactors[i] = -nextOptionLong("major nav events percentage"); } else if (opt.equals("--pct-appswitch")) { int i = MonkeySourceRandom.FACTOR_APPSWITCH; mFactors[i] = -nextOptionLong("app switch events percentage"); } else if (opt.equals("--pct-flip")) { int i = MonkeySourceRandom.FACTOR_FLIP; mFactors[i] = -nextOptionLong("keyboard flip percentage"); } else if (opt.equals("--pct-anyevent")) { int i = MonkeySourceRandom.FACTOR_ANYTHING; mFactors[i] = -nextOptionLong("any events percentage"); } else if (opt.equals("--pct-pinchzoom")) { int i = MonkeySourceRandom.FACTOR_PINCHZOOM; mFactors[i] = -nextOptionLong("pinch zoom events percentage"); } else if (opt.equals("--pkg-blacklist-file")) { mPkgBlacklistFile = nextOptionData(); } else if (opt.equals("--pkg-whitelist-file")) { mPkgWhitelistFile = nextOptionData(); } else if (opt.equals("--throttle")) { mThrottle = nextOptionLong("delay (in milliseconds) to wait between events"); } else if (opt.equals("--randomize-throttle")) { mRandomizeThrottle = true; } else if (opt.equals("--wait-dbg")) { // do nothing - it's caught at the very start of run() } else if (opt.equals("--dbg-no-events")) { mSendNoEvents = true; } else if (opt.equals("--port")) { mServerPort = (int) nextOptionLong("Server port to listen on for commands"); } else if (opt.equals("--setup")) { mSetupFileName = nextOptionData(); } else if (opt.equals("-f")) { mScriptFileNames.add(nextOptionData()); } else if (opt.equals("--profile-wait")) { mProfileWaitTime = nextOptionLong("Profile delay" + " (in milliseconds) to wait between user action"); } else if (opt.equals("--device-sleep-time")) { mDeviceSleepTime = nextOptionLong("Device sleep time" + "(in milliseconds)"); } else if (opt.equals("--randomize-script")) { mRandomizeScript = true; } else if (opt.equals("--script-log")) { mScriptLog = true; } else if (opt.equals("--bugreport")) { mRequestBugreport = true; } else if (opt.equals("--periodic-bugreport")){ mGetPeriodicBugreport = true; mBugreportFrequency = nextOptionLong("Number of iterations"); } else if (opt.equals("-h")) { showUsage(); return false; } else { System.err.println("** Error: Unknown option: " + opt); showUsage(); return false; } } } catch (RuntimeException ex) { System.err.println("** Error: " + ex.toString()); showUsage(); return false; } // If a server port hasn't been specified, we need to specify // a count if (mServerPort == -1) { String countStr = nextArg(); if (countStr == null) { System.err.println("** Error: Count not specified"); showUsage(); return false; } try { mCount = Integer.parseInt(countStr); } catch (NumberFormatException e) { System.err.println("** Error: Count is not a number"); showUsage(); return false; } } return true; }
所以,Monkey运行结果中对应的就应该是:
至此,monkey运行结果的查看结束。
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化测试工具——Monkey
- Android自动化压力测试图解教程——Monkey工具
- Android自动化压力测试图解教程——Monkey工具
- Android自动化压力测试图解教程——Monkey工具
- Android自动化压力测试图解教程——Monkey工具
- Android自动化压力测试图解教程——Monkey工具
- [经典]技术面试宝典: 很全面的算法和数据结构知识(含代码)
- APK包的格式
- APK签名
- hdu1596(Dijkstra)
- 第三方控件介绍
- Android自动化测试工具——Monkey
- WEB前端:响应式实现原理
- 关于libmad开源mp3音频解码库的使用
- SQL 用于各种数据库的数据类型
- 485通信了解基础知识
- shiro整合spring
- Golang 父子对象与JSON互相转换以及struct结构体内部的反引号该如何定义字段编码生成json字符串的写法
- nodejs
- Python实现Pat 1006. Sign In and Sign Out (25)