Monkey测试系列:3. 源码解析

源码下载

monkey源码下载地址:
http://download.csdn.net/download/kingzhongmu/9424373

Monkey 测试的入口

在Monkey.java中有一个main函数

public static void main(String[] args) {
        int resultCode = (new Monkey()).run(args);
        System.exit(resultCode);
    }

真正的逻辑执行是在run函数中



Monkey 的执行流程

private int run(String[] args) {
  processOptions();//处理从命令行接收到的参数,并赋给相应的变量
  loadPackageLists();//加载设置的白名单或者黑名单
  getSystemInterfaces();//获得系统接口
  getMainApps();//获取要执行的activity
  if (mScriptFileName != null) {
      mEventSource = new MonkeySourceScript(mScriptFileName);//如果有脚本文件输入的话,就new一个MonkeySourceScript对象。
      mEventSource.setVerbose(mVerbose);
  } else {
      mEventSource = new MonkeySourceRandom(mSeed, mMainApps, mThrottle, mThrottleTouch, mThrottleKey);//如果没有脚本文件输入的话,就new一个MonkeySourceRandom对象。也是我们常用的简单操作。
      mEventSource.setVerbose(mVerbose);
  }    
  ((MonkeySourceRandom) mEventSource).setFactors(i, mFactors[i]);//设置事件的操作比例。
  mEventSource.validate();//调整事件比例。
  ((MonkeySourceRandom) mEventSource).generateActivity();//随机事件下,产生一个随机的Activity。
   int crashedAtCycle = runMonkeyCycles();//monkey的核心事件注入逻辑
}




Monkey 的类结构

monkey源代码主要有若干个java文件,除了入口Monkey.java文件及工具文件外,另外还有两组类文件,分别是以MonkeyEventSource为接口类的事件流处理类(MonkeySourceRandom、MonkeySourceScript等类,分别处理随机事件流和monkey脚本事件流),以及以MonkeyEvent为接口类的事件操作类(MonkeyActivityEvent、MonkeyKeyEvent、MonkeyMotionEvent、MonkeyFlipEvent、MonkeyThrottleEvent等类)

事件处理类

事件操作类




随机事件的生成

public MonkeyEvent getNextEvent() {
    //从MonkeyEvent队列mQ里取出MonkeyEvent事件,如果mQ当前是空的话,就生成一个事件。否则就取出队列的第一个事件。
        if (mQ.isEmpty()) {
            generateEvents();
        }
        mEventCount++;
        MonkeyEvent e = mQ.getFirst();
        mQ.removeFirst();
        return e;
    }
private void generateEvents() {
        float cls = mRandom.nextFloat();    //由seed生成的Random,取一个随机数
        int lastKey = 0;
        //依据随机数的大小,执行生成不同手势的MotionEvent事件(generatePointerEvent实质上是生成MotionEvent事件)。
        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;
        }
        ......
        MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, lastKey);
        //将事件添加到队列
        mQ.addLast(e);

        e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
        mQ.addLast(e);
    }




事件注入

private int runMonkeyCycles() {
     ······
     //获取事件
     MonkeyEvent ev = mEventSource.getNextEvent();
     //注入事件
     int injectCode = ev.injectEvent(mWm, mAm, mVerbose);
     ······ 
}




Monkey的代码框架

  • 主控模块:主控模块即Monkey类,是入口函数所在类,主要负责参数解析和赋值、初始化运行环境(导入package列表、检查内部配置、申请系统资源、初始化事件源、启动监控等)、执行runMonkeyCycles()方法针对不同的事件源开始获取并执行不同的事件。

  • 监控模块:监控部分包括异常监控和网络监控两部分。异常监控通过ActivityWatch类来实现,主要监控Activity的Crash和ANR事件。网络监控通过MonkeyNetworkMonitor类来实现,主要用于统计运行期间移动网络和Wi-Fi网络的链接时长。

  • 事件源模块:事件源代表不同的事件来源。以MonkeyEventSource为基类,衍生出三个Source类,分别代表网络来源(如Monkeyrunner)、随机事件来源(常规Monkey命令)、脚本来源(通过-f参数指定的脚本)三种事件来源。事件源要做的事情有:从对应来源获取信息,并生成对应的事件,将其插入事件队列中。

  • 事件模块:事件代表了各种用户操作类型。以MonkeyEvent为基类,衍生出各种Event类,每一个Event类代表一种用户操作类型,如常见的点击、输入、滑动事件等。MonkeyEvent抽象类中提供了intinjectEvent()方法,用于执行对应的事件。

这里写图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值