MonkeyRunner 自动化测试 Android 应用入门示例

这里总结如何使用 monkeyrunner 来自动化测试 android apk 应用。html

1. 环境准备

1.1 python 安装

下载 pythonmsi 包,直接点击 next,安装。java

1.2 java jdk 安装

由于 android sdk 这些是基于 java jvm,因此须要须要 java jdk 环境node

1.3 android sdk 安装

使用 android sdk manager 管理工具,来安装 android sdk toolsandroid sdk platform_tools。这里也须要安装一个版本的 sdk platform
截图以下:python

图片描述

因为 GWF 的缘由,使用 google 的源安装 sdk 比较困难,咱们能够换成国内的源。点击这里android

1.4 windows 下配置环境变量

monkeyrunnerandroid platform_tools 中提供的一个自动化测试接口工具。能够经过脚原本模拟 APP 业务流程。git

这里配置github

JAVA_HOME=[你的 Java jre 文件存放根路径]

ANDROID_HOME=[你的 Android sdk 文件存放根路径]

Path=%JAVA_HOME%\bin;%JAVA_HOME%\lib;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;C\python

这里这样设置,是为了能够在 dos 情形下,直接执行对应的命令,如 python, monkeyrunnershell

至此,环境搭建成功。windows

2. MonkeyRunner 是什么

MonkeyRunner 是一个测试工具,经过运行 python 脚原本模拟 Android 手机界面的点击事件来测试。通常测试步骤:api

模拟界面点击事件 --> 事件结果截图 --> 截图与正确图片比较来判断测试结果是否经过

来一段简单的 python 测试脚本:

# hello.py
# coding: utf-8

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage

# 链接设备
device = MonkeyRunner.waitForConnection([delay secs], [deviceid]);

# 安装APP
apkFilePath = "E:/myapp.apk";
device.installPackage(apkFilePath);

# 启动 APP
# 自行 google package 和 activity 是什么
package = "com.test.myapp";
activity = "com.test.Android.myappActivity";
runComponent = package + "/" + activity;
device.startActivity(component=runComponent);

# 这里通常让脚本暂停一段时间,使得APP成功启动起来
MonkeyRunner.sleep(3);

# 下面开始模拟界面事件
# 1. 点击事件
device.touch(x, y, "DOWN_AND_UP");
MonkeyRunner.sleep(1);

# 2. 输入事件
# 先发焦点聚焦到输入控件上,而后 type 内容
device.touch(x, y, "DOWN_AND_UP");
MonkeyRunner.sleep(1);
device.type(value);
MonkeyRunner.sleep(1);

# 3. 模拟按键按下,如后退,home按键按下
# 这里第一个参数值的定义能够
devie.press("KEYCODE_BACK", "DOWN_AND_UP");
MonkeyRunner.sleep(1);

# 4. 界面滑动
device.drag((x1, y1), (x2, y2));
MonkeyRunner.sleep(1);

# 点击事件触发,界面开始变化,截屏比较
imagetobecompared = MonkeyRunner.loadImageFromFile([image file path]);
screenshot = device.takeSnapshot();
if screenshot.sameAs(imagetobecompared, 0.9):
  print "2张图片相同";
else:
  print "2张图片不相同";

代码中的 KEYCODE_BACK 这样的取值,能够参考

按照上方测试流程,咱们须要作什么:

  1. 正确的截图如何获取并保存下来

  2. 设定测试模拟器分辨率,而后获取控件坐标 (x, y)

缺陷有哪些:

  1. 来点击控件是经过坐标来肯定的,这样在不一样分辨率的情形下,这个坐标是不同的,测试不一样分辨率机型要写不一样的测试脚本

  2. 图片的比对,这个不怎么准确

3. 咱们须要作什么

android sdk 下提供了一些工具来帮助咱们获取界面中控件的坐标,例如 uiautomatorviewer, hierarchyviewer, monitor

3.1 uiautomatorviewer

这个能够打开后,经过点击界面上的控件,来获取控件的坐标。直接在 dos 下运行命令:

uiautomatorviewer

执行后效果图:

图片描述

这里能够看到 bounds 属性的值 [256, 165][320, 223]。这个是控件的左上和右下点的坐标,能够经过这2个点计算出中心点的坐标。

获取一个控件的坐标都这么麻烦。。。

3.2 MonkeyRecorder

这个工具提供了一套记录用户操做界面行为的操做,例如 TOUCH, PRESS, TYPE, Drag 这些操做。这个工具在 tools
或者 platform-tools 下都没有看到,不过能够经过代码来调用。

# coding: utf-8

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage
from com.android.monkeyrunner.recorder import MonkeyRecorder as recorder

device = MonkeyRunner.waitForConnection(3, "127.0.0.1:30054");

# 启动 recorder
recorder.start(device);

启动后的截图以下:

图片描述

点击界面上的控件,或者 type something, 或者 Fling 这些操做,都会在右侧中留下操做记录,这里有点击点的坐标,
或者 type value这些操做。

导出操做到文件中,在 py 脚本文件中,实现起来就方便了。(强烈推荐这个来记录操做流程)

3.3 如何保存正确的截屏文件用于后续的比对

目前没有发现比较方便快捷的截屏保存操做。因此在这里实现了一小段截屏脚本,使用流程:

  1. 启动模拟器,安装APP并启动咱们须要测试的APP

  2. 运行咱们的脚本 mkr console.py,这里有个 dos 窗口

  3. 在模拟器中操做APP,若是须要截屏,在步骤2中打开的 dos 窗口中输入 save,保存截图

附上代码:

mkr.bat 文件内容

@echo off
monkeyrunner %~dp0%1

console.py 文件内容

# console.py
# coding: utf-8

# 链接模拟器
...

# 这里开始根据输入的命令执行对应的操做
# save: 截屏并保存 png 图片
# quit:退出
cmdstr = raw_input(">>>");
while cmdstr != "quit":
  
  # 截图保存
  if cmdstr == "save":
    fpng = time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png";
    de.saveImage(os.path.join(pydir, "images", fpng), "png");

  cmdstr = raw_input(">>>");

注:

这里运行 raw_input 命令的时候会卡主。参考下面的 Q&A 部分,问题1

4. 如何对付上述流程中的缺陷

4.1 控件坐标问题

使用空间坐标来操做控件,当屏幕分辨率改变时,控件坐标天然会改变。难道咱们每一个坐标都写一个测试脚本。
这里有2种解决方式:

  1. 先固定一个屏幕分辨率,而后在新分辨率下从新计算控件坐标

  2. 使用控件 id 来操做控件

方式1,假定咱们的测试脚本是在 320 * 568 分辨率下控制控件 (120, 200) 来作点击操做。原来的代码

device.touch(120, 200, "DOWN_AND_UP");

如今须要改成

dw = device.getProperty("display.width");
dh = device.getProperty("display.height");

nx = int(120 / 320.0 * int(dw));
ny = int(200 / 320.0 * int(dh));

另一种方式是,经过控件 id 来获取控件,操做控件。对应的工具 hierarchyviewer

4.2 hierarchyviewer

dos 窗口下输入

> hierarchyviewer

运行该命令的时候,最好先把模拟器的界面调整到你须要取控件 id 的控件。上方命令成功后,会有以下截图:

图片描述

这时选中 activity 点击 Load View Hierarchy 显示以下界面:

图片描述

这里看到有的控件的下方有 id/content 这样的内容,这个就是控件的 id

使用代码示例以下:

# coding: utf-8

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage
from com.android.chimpchat.hierarchyviewer import HierarchyViewer
from com.android.monkeyrunner.easy import By

device = MonkeyRunner.waitForConnection(1, "127.0.0.1:30054");

hdevice = device.getHierarchyViewer();

# 经过id获取node
vnode = hdevice.findViewById("id/content");

# 经过node,获取位置
point = hdevice.getAbsolutePositionOfView(vnode);

pcenter = hdevice.getAbsoluteCenterOfView(vnode);

# 获取node中的文本内容
txt = hdevice.getText(vnode);

4.3 EasyMonkeyDevice

# coding: utf-8

...
from com.android.monkeyrunner.easy import EasyMonkeyDevice
from com.android.monkeyrunner.easy import By

# 链接设备,启动APP
...

easydevice = EasyMonkeyDevice(device);
easydevice.touch(By.id("id/content"), MonkeyDevice.DOWN_AND_UP);

Q & A

1. monkeyrunner raw_input() 接收输入后不运行后面的代码

这个被发现是 jpython 的一个 bug, python 版本 jython-standalone-2.5.3.jar
当前你使用的 jpython 版本能够在 ${ANDROID_HOME}\tools\lib 下能够看到。

fix:

https://code.google.com/p/android/issues/detail?id=56318

2. 使用每天模拟器建立一个虚拟设备,使用 adb devices 检查不出来

这里是由于咱们要手动链接每天模拟器,这里须要 ipport

图片描述

从上面的截图,能够看到文件夹 TianTian, TianTian_1, TianTian_2 ...

这里的每个文件夹内容表示一个模拟器,我这里建立了3个模拟器,因此有三个文件夹。要链接哪一个模拟器,查看对应
模拟器下的链接 ip 地址,能够查看下面内容:

<!--/TianTian.vbox-->
<VirtualBox ...>
  <Machine ...>
    ...
    <Hardware ...>
      ...
      <Network>
        <Adapter ...>
          ...
          <NAT>
            ...
            <Forwarding name="AdbPort" proto="1" hostip="127.0.0.1" hostport="6555" guestip="10.0.2.15" guestport="5555"/>
          </NAT>
        </Adapter>
      </Network>
    </Hardware>
  </Machine>
</VirtualBox>

这里看到链接地址:hostip, hostport

dos 下运行命令:

adb connect [hostip]:[hostport]

链接模拟器,到此 type 下面命令就能够查询到模拟器了。

adb devices

3. MonkeyRunner 字符编码问题

dos 命令 chcp 的介绍和使用,点击这里

显示当前 dos 环境下的编码格式

> chcp

切换到简体中文编码格式

> chcp 936

切换到英文编码格式

> chcp 437

切换到 utf-8 编码格式

> chcp 65001

若是在 monkeyrunner 中打印内容,报以下错误:

LookupError: unknown encoding 'ms936'

这个就是编码问题,执行上面的 chcp 命令,切换咱们须要的编码。

参考

android sdk 等工具安装

Android自动化压力测试快速入门教程(图解)——MonkeyRunner

一个简单的monkeyRunner例子

ADB Shell

每天模拟器正确USB调试链接方法

monkeyrunner api

相关文章
相关标签/搜索