android Monkey测试源码分析之二
2017-04-15 11:28
459 查看
3. 随机运行模式
在上个小节中,monkey有4种运行模式,原理都是一样的,就以随机运行模式为例来论述。3.1 准备工作
在run方法中,有关随机运行模式代码如下,mEventSource = new MonkeySourceRandom(mRandom, mMainApps, mThrottle, mRandomizeThrottle, mPermissionTargetSystem); mEventSource.setVerbose(mVerbose); // set any of the factors that has been set for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) { if (mFactors[i] <= 0.0f) { ((MonkeySourceRandom) mEventSource).setFactors(i, mFactors[i]); } } // in random mode, we start with a random activity ((MonkeySourceRandom) mEventSource).generateActivity();
首先构造MonkeySourceRandom对象,然后调用其setFactors设置事件的百分比,最后调用generateActivity方法。
MonkeySourceRandom的构造方法如下,
public MonkeySourceRandom(Random random, List<ComponentName> MainApps,
long throttle, boolean randomizeThrottle, boolean permissionTargetSystem) {
// default values for random distributions
// note, these are straight percentages, to match user input (cmd line args)
// but they will be converted to 0..1 values before the main loop runs.
mFactors[FACTOR_TOUCH] = 15.0f; // 为这些事件所占百分比赋初值。
mFactors[FACTOR_MOTION] = 10.0f;
mFactors[FACTOR_TRACKBALL] = 15.0f;
// Adjust the values if we want to enable rotation by default.
mFactors[FACTOR_ROTATION] = 0.0f;
mFactors[FACTOR_NAV] = 25.0f;
mFactors[FACTOR_MAJORNAV] = 15.0f;
mFactors[FACTOR_SYSOPS] = 2.0f;
mFactors[FACTOR_APPSWITCH] = 2.0f;
mFactors[FACTOR_FLIP] = 1.0f;
// disbale permission by default
mFactors[FACTOR_PERMISSION] = 0.0f;
mFactors[FACTOR_ANYTHING] = 13.0f;
mFactors[FACTOR_PINCHZOOM] = 2.0f;
mRandom = random;
mMainApps = MainApps;
// 构造一个MonkeyEventQueue 对象
mQ = new MonkeyEventQueue(random, throttle, randomizeThrottle);
mPermissionUtil = new MonkeyPermissionUtil();
mPermissionUtil.setTargetSystemPackages(permissionTargetSystem);
}
MonkeyEventQueue定义如下,
public class MonkeyEventQueue extends LinkedList<MonkeyEvent> { private Random mRandom; private long mThrottle; private boolean mRandomizeThrottle; public MonkeyEventQueue(Random random, long throttle, boolean randomizeThrottle) { super(); mRandom = random; mThrottle = throttle; mRandomizeThrottle = randomizeThrottle; } @Override public void addLast(MonkeyEvent e) { super.add(e); if (e.isThrottlable()) { long throttle = mThrottle; if (mRandomizeThrottle && (mThrottle > 0)) { throttle = mRandom.nextLong(); if (throttle < 0) { throttle = -throttle; } throttle %= mThrottle; ++throttle; } super.add(new MonkeyThrottleEvent(throttle)); } } }
MonkeyEventQueue继承于LinkedList,并且仅仅重写了addLast方法。
为了保存各种MonkeyEvent。
setFactors方法重新为所占百分比赋值。
public void setFactors(float factors[]) { int c = FACTORZ_COUNT; if (factors.length < c) { c = factors.length; } for (int i = 0; i < c; i++) mFactors[i] = factors[i]; }
generateActivity方法产生Activity事件。
public void generateActivity() { MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get( mRandom.nextInt(mMainApps.size()))); mQ.addLast(e); }
3.2 测试
MonkeySourceRandom的getNextEvent方法如下,public MonkeyEvent getNextEvent() { if (mQ.isEmpty()) { generateEvents(); } mEventCount++; MonkeyEvent e = mQ.getFirst(); mQ.removeFirst(); return e; }
逻辑很简单,从MonkeyEventQueue中取出下一条事件。如果没有,就产生事件。
generateEvents方法如下,产生各种事件。
private void generateEvents() { float cls = mRandom.nextFloat(); int lastKey = 0; if (cls < mFactors[FACTOR_TOUCH]) { generatePointerEvent(mRandom, GESTURE_TAP); return; } else if (cls < mFactors[FACTOR_MOTION]) { generatePointerEvent(mRandom, GESTURE_DRAG); return; } else if (cls < mFactors[FACTOR_PINCHZOOM]) { generatePointerEvent(mRandom, GESTURE_PINCH_OR_ZOOM); return; } else if (cls < mFactors[FACTOR_TRACKBALL]) { generateTrackballEvent(mRandom); return; } else if (cls < mFactors[FACTOR_ROTATION]) { generateRotationEvent(mRandom); return; } else if (cls < mFactors[FACTOR_PERMISSION]) { mQ.add(mPermissionUtil.generateRandomPermissionEvent(mRandom)); return; } // The remaining event categories are injected as key events for (;;) { if (cls < mFactors[FACTOR_NAV]) { lastKey = NAV_KEYS[mRandom.nextInt(NAV_KEYS.length)]; } else if (cls < mFactors[FACTOR_MAJORNAV]) { lastKey = MAJOR_NAV_KEYS[mRandom.nextInt(MAJOR_NAV_KEYS.length)]; } else if (cls < mFactors[FACTOR_SYSOPS]) { lastKey = SYS_KEYS[mRandom.nextInt(SYS_KEYS.length)]; } else if (cls < mFactors[FACTOR_APPSWITCH]) { MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get( mRandom.nextInt(mMainApps.size()))); mQ.addLast(e); return; } else if (cls < mFactors[FACTOR_FLIP]) { MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen); mKeyboardOpen = !mKeyboardOpen; mQ.addLast(e); return; } else { lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1); } if (lastKey != KeyEvent.KEYCODE_POWER && lastKey != KeyEvent.KEYCODE_ENDCALL && lastKey != KeyEvent.KEYCODE_SLEEP && PHYSICAL_KEY_EXISTS[lastKey]) { break; } } MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, lastKey); mQ.addLast(e); e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey); mQ.addLast(e); }
runMonkeyCycles使用while循环调用获取MonkeyEvent然后注入事件。
MonkeyEvent ev = mEventSource.getNextEvent(); if (ev != null) { int injectCode = ev.injectEvent(mWm, mAm, mVerbose);
终止的条件如下,
while (!systemCrashed && cycleCounter < mCount) {
1,系统已经崩溃
2,重复次数已经到了设置次数。
这样很简单就完成测试了。
4. monkey框架结构
Monkey的代码比较少,结构简单。主要功能分为2块1,产生事件
2,触发事件
Monkey.java
程序的入口,调度中心,解析参数,构造不同的MonkeyEventSource子类。
MonkeyEventSource.java
4中模式分别对应不同的MonkeyEventSource
例如, MonkeySourceScript/MonkeySourceRandomScript/ MonkeySourceNetwork/ MonkeySourceRandom
MonkeyEvent.java
各种事件的具体实现。如MonkeyKeyEvent/ MonkeyMotionEvent等等。
最后都是调用AM/WM/PM 来实现。
相关文章推荐
- Android稳定性测试-- Monkey源码分析
- Monkey源码分析番外篇之Android注入事件的三种方法比较
- Android 4.3 Monkey自动化测试工具被killed的原因分析
- 【Android M】Monkey命令源码及是否处于monkey测试的判断方法
- android_测试分析(monkey,monekyrunner,uiautomator,Robotium,单元测试,启动性能)cts测试
- Android APP压力测试 之Monkey日志自动分析脚本
- Monkey源码分析番外篇之Android注入事件的三种方法比较
- Android自动化测试框架开发(二)Monkey、MonkeyRunner介绍和分析
- [Android]开源中国源码分析之二---DrawerLayout
- Android测试三----TestSuite源码分析。
- Android APP压力测试(三)之Monkey日志自动分析脚本
- android ANR源码分析 --- 之二
- [Android 测试] 压力稳定性测试之: Monkey 详解分析脚本
- Android 4.3 Monkey自动化测试工具被killed的原因分析
- 【Android测试】【第七节】Monkey——源码浅谈
- Android测试四----TestRunner源码分析。
- 【Android测试】【第七节】Monkey——源码浅谈
- 【android】Monkey源码分析、事件注入
- 由Monkey测试引发的跨多个进程的Android系统死锁问题分析
- Android工程直接调用monkey源码进行压力测试