java使用monkeyrunner_MonkeyRunner 实践----用 java 来编写脚本

前言

之前在论坛看到有同行在用 MonkeyRunner 测试一些 Android 的操作, 使用的是 Python 写的脚本, 就设想应该也是可以用 java 来写脚本的, 毕竟本身 MonkeyRunner 就是用 java 写的, 并调用了一些 Android 平台的 Api. 在网上上搜索了一下 确实也可以,只是网上的例子基本都是直接使用 Android 的 api, 相对来说看起来不是那么友好, 于是本着学习的态度,就自己尝试着学习下 MonkeyRunner 的源代码, 然后试着改下, 再稍微的封装下, 于是便有了这篇帖子. 本帖子中所描述并且给出的代码, 源于 Android 的基础 Api,二次进行的简单修改, 目的在于研究和学习之用. 同时用 java 编写类似 MonkeyRunner 的代码并不需要 MonkeyRunner.jar, 特此声明.

MonkeyRunner 基本结构

8018bf6053285ae43cb1d6470a377929.png

com.android.monkeyrunner.controller 和 com.android.monkeyrunner.recorder 包下为 MonkeyRunner 的 UI 界面, 标准的 java swing 编写, 界面布局非常简单, 并非像 uiautomatorview 一样使用的 Eclipse RCP.

com.android.monkeyrunner 包下才是最主要的东西, 由 Python 文件包含的信息会经由 JythonUtils 进行分析,然后在调用 MonkeyRunner.java 等这些主要的操作类进行操作.

最主要的操作类为 MonkeyRunner, MonkeyDevice, MonkeyView, MonkeyImage, 下文将要进行编写和封装的自定义类,也将和这几个关键类进行匹配.

如果想在 IDE 中编译 MonkeyRunner 的源代码需要 ddmlib.jar,guavalib.jar,sdklib.jar,chimpchat.jar,hierarchyviewer2lib.jar 这五个 jar 包,而应于我们自己编写的也需要着五个包,所以并不需要 MonkeyRunner.jar.

基本思路

简单说就是把 MonkeyRunner 的核心的几个类自己在写一遍, 因为本身并不复杂,所以写起来也用不了多少时间, 而且很多的方法基本都是删减点,然后直接拷贝过去就好了.

扩展对照 MonkeyRunner

MteMonkeyRunner

Description

MonkeyRunner

MteMonkeyRunner

提供一些必要的操作入口,比如关键的连接设备等方法

MonkeyDevice

MteMonkeyDevice

提供 Android 设备包括模拟器和真机的基本操作方法

MonkeyView

MteMonkeyView

提供标准的界面 view object 的常规操作和封装

MonkeyImage

MteMonkeyImage

提供截图的一些基本操作

举个栗子

MonkeyRunner public static MonkeyDevice waitForConnection(PyObject[] args, String[] kws) {

ArgParser ap = JythonUtils.createArgParser(args, kws);

Preconditions.checkNotNull(ap);

long timeoutMs;

try {

double timeoutInSecs = JythonUtils.getFloat(ap, 0);

timeoutMs = (long) (timeoutInSecs * 1000.0);

} catch (PyException e) {

timeoutMs = Long.MAX_VALUE;

}

IChimpDevice device = chimpchat.waitForConnection(timeoutMs,

ap.getString(1, ".*"));

MonkeyDevice chimpDevice = new MonkeyDevice(device);

return chimpDevice;

}

MteMonkeyRunner public static MteMonkeyDevice waitForConnection(long timeoutMs, String deviceId) {

setChimpChat();

IChimpDevice device = chimpchat.waitForConnection(timeoutMs, deviceId);

MteMonkeyDevice mmd = new MteMonkeyDevice(device);

return mmd;

}

setChimpChat()方法为本人自己添加的, 因为如果直接调用 MteMonkeyRunner 或者是 MonkeyRunner 的方法因为 chimpchat 并没有初始化,所以必然抛空指针,所以我自己对 chimpchat 进行了初始化, 请参考下面的代码:

java

static void setChimpChat() {

TreeMap options = new TreeMap();

options.put("backend", "adb");

chimpchat = ChimpChat.getInstance(options);

}

必要的了解

不管是 MonkeyRunner 还是我自己胡写的 MteMonkeyRunner 说穿了主要就是调用下面的几个个关键的 API:

ChimpChat

IChimpDevice

IChimpView

IChimpImage

这几个类都来自于 com.android.chimpchat.core package, 也就是 chimpchat.jar. 这个类包中包含了很多基础的关键的 Api, 比如 调用 adb 和 HierarchyViewer 等.

MteMonkeyRunner 基本结构

就像前面提到的我只是把 MonkeyRunner 几个主要的类重写和拷贝了下, 在简单的进行了修改.只有四个主要的类文件.其实就是本人无耻的把对应方法中分析 python 参数的代码都删除掉了. 因为出发点为用 java 直接写代码, 所以并没有重新写个 UI 出来, 但是我分析过 MonkeyRunner 对应的界面代码, 真是挺对付的....

4eb2265ce806562ae138de4c521c8fde.png

举个栗子 package test.example.testcase;

import java.util.Collection;

import com.mte.android.mmr.MteMonkeyDevice;

import com.mte.android.mmr.MteMonkeyImage;

import com.mte.android.mmr.MteMonkeyRunner;

import com.mte.util.DateTimeUtil;

public class MteMonkeyRunnerTest {

public static void main(String args[]){

String apppath="./app/android/oschina/osc-android-app-2.2.apk";

String packageName="net.oschina.app";

String startActivity="net.oschina.app/.AppStart";

MteMonkeyDevice device=MteMonkeyRunner.waitForConnection(100000,"HC477WY00656");

System.out.println("Device name is : " + device.getProperty("build.model"));

for(String prop:device.getPropertyList()){

System.out.println(prop +" : "+device.getProperty(prop));

}

device.installPackage(apppath);

device.startActivity(startActivity);

MteMonkeyRunner.sleep(30000);

MteMonkeyImage image=new MteMonkeyImage(device.takeSnapshot());

image.writeToFile("./screen/MteMonkeyRunnerTest"+DateTimeUtil.getCurrentDateTime()+".png", "png");

MteMonkeyRunner.sleep(10000);

Collection viewLst=device.getViewIdList();

System.out.println("device.getViewIdList() is : "+viewLst.size());

if(viewLst.size()>=1){

for(String prop:viewLst){

System.out.println(prop);

}

}

MteMonkeyRunner.sleep(20000);

device.removePackage(packageName);

device.dispose();

}

}

可能出现的问题以及免责声明

本人在写完基本方法测试脚本的时候, 有时候发现 当我使用 device.shell() 或者是 device.getViewIdList() 等方法时候,会抛出异常, 而且在真机通过了,反而在模拟器上出现问题, 虽然花时间找了下解释, 但是基本上算是没解决, 我在见了自己的 MteMonkeyRunner 的类的时候,只是删除了对应的 python 的参数处理,而且关键的方法基本没变, 怀疑是本人的 Mac 环境问题,所以本人也很无奈, 大家如果有兴趣在使用的时候,请注意并请见谅.写的这些本身就是为了学习研究, 通过一些很具体的实践加深了解, 分析源代码是非常有效的学习方式.

参考

本帖子中的 MteMonkeyRunner 所有源代码都可以在 https://github.com/PandaSense/mtesense 中下载到,包名为 com.mte.android.mmr, 可以单独使用, 只要你把,帖子前面说明的五个 jar 添加到对应 project 的 java build path 就可以.

其他设想

扩展下 MonkeyRunner 的 UI 界面多加一些有用的操作 (自带的界面非常简陋)

接受参数化的脚本,直接跑测试等等

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值