MonkeyTalk Java API 使用教程

Haibo · 2015年08月08日 · 最后由 lifen 回复于 2016年01月07日 · 3421 次阅读
本帖已被设为精华帖!

MonkeyTalk 文章合集 By penghaibo203

MonkeyTalk Java API 使用教程
Ant 编译 MonkeyTalk Agent 方法介绍
移动端 App UI 自动化测试浅谈
MonkeyTalk 自动化持续集成方案
MonkeyTalk 移动 App 自动化测试
MonkeyTalk Agent 安装方法介绍

MonkeyTalk 简介

简单来说,MonkeyTalk 是一个移动端的自动化测试框架,支持 Android,iOS,Webapp 的功能自动化测试。用户既可以使用 MonkeyTalk 集成开发环境进行测试步骤的录制回放,也可以使用 Java API 编写测试脚本进行自动化测试。详细介绍可以参考访问MonkeyTalk的官方网站。这里,我们主要介绍如何使用 MonkeyTalk 的 Java API 进行自动化测试。

前提知识

使用 MonkeyTalk Java API 要求你熟悉 Java 开发和Junit 测试

使用指导

首先你需要下载一个 MonkeyTalk 的开发包,并从其中的 Java 目录下提取出 monkeytalk-java-all-in-one.jar 文件。这个架包包含了 MonkeyTalk 的 Java API 和一起其他需要用到的架包。
然后,你可以在你 Eclipse 或者 Android studio 等你熟悉的开发环境中建立一个 java 工程,并将上述架包连同 Junit 一起导入到工程中。下图是一个 Eclipse 中工程目录的截图。
此处输入图片的描述

接下来,我们建立一个测试工程,下面是一个基于 MonkeyTalk API 编写的自动化测试脚本。

import java.io.File;
import java.io.IOException;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.gorillalogic.monkeytalk.java.MonkeyTalkDriver;
import com.gorillalogic.monkeytalk.java.api.Application;

public class LoginTest {
    private static MonkeyTalkDriver mt;
    private Application app;

    @BeforeClass
    public static void beforeClass() throws IOException {
        mt = new MonkeyTalkDriver(new File("."), "iOS");
        mt.setThinktime(500);
        mt.setTimeout(5000);
    }

    @Before
    public void before() {
        app = mt.app();
    }

    @Test
    public void testLogin() {
        app.input("username").enterText("fred");
        app.input("password").enterText("pass");
        app.button("LOGIN").tap();
    }
}

@BeforeClass的注解方法中,我们启动 MonkeyTalkDriver 并连接到一个 iOS 设备上 app。在@Before的注解方法中,我们获取被测的应用程序。然后我们在 test 方法中编写测试步骤的脚本。接下来我们就可以通过 Junit 运行我们的测试代码。在 Eclipse 中,右键点击Run As > JUnit Test即可运行。当然,在此之前你要在手机或者模拟器上启动你的待测 app。
此处输入图片的描述

关于 MonkeyTalkDriver

Monkeytalk 类开启了一个连接电脑和运行在移动设备上的被测 app 的接入点。我们可以通过如下的方式配置连接的设备类型。

MonkeyTalkDriver mt = new MonkeyTalkDriver(new File("."), "iOS");

第一个参数是保存截屏或者外包脚本的目录。第二个参数是 agent 的类型,可以是 iOS(对于真机和模拟器),Android(对于通过 wifi 连接的真机),AndroidEmulator(对于模拟器或者 usb 连接的真机)。
如果是通过 iOS 真机连接测试,你必须保证你的设备和电脑在同一个 wifi 网段上可以通过如下的方式连接:

MonkeyTalkDriver mt = new MonkeyTalkDriver(new File("."), "iOS", "123.456.78.90");

如果是运行在 Android 真机上的应用程序,我们可以通过下面的方式连接:

MonkeyTalkDriver mt = new MonkeyTalkDriver(new File("."), "AndroidEmulator");
mt.setAdb(new File("/path/to/android-sdk/platform-tools/adb"));

当然,MonkeyTalk driver 也可以设置其他属性,如 timeout 或者 thinktime。

mt.setTimeout(5000);
mt.setThinktime(750);

最后,我们设置一个待测 app 的入口

Application app = mt.app();

上面的命令初始化了一个待测 app 的 MonkeyTalk 连接,因此这部分代码通常放在@Before注解函数中。另一方面,MonkeyTalkDriver 在每个测试集中只需要创建一次即可,因此,我们通常将其在@BeforeClass中初始化为一个静态方法。

如何查找 MonkeyId

在开始写测试脚本之前,我们先要找到一个 UI 元素的 ID,才能对其进行操作。我们可以通过 MonkeyTalk IDE 进行录制获取元素 ID,也可以通过 IDE 的 Component Tree 视图查看当前屏幕的控件树。或者你还可以直接在程序源代码中寻找。根据我的经验,一般第一种方式会更快捷,在这里推荐下。

Action 的用法

Action 顾名思义是指控件的动作,当我们通过 MonkeyId 找到一个控件之后,就可以通过 Action 来指定对该控件的动作,从而完成相应的交互事件。比如我们想要从 app 中获取页面元素的关键数据来判断是否正确,或者用于后续的操作。这个功能我们可以通过 get 方法来实现,举个例子,我们获取一个 label 中显示的文本:

String val = app.label("title").get();

这样,label 中的文本就复制给了一个 Java 变量 val,我们可以通过 verify 方法来判定它:

String val = app.label("title").get();
assertThat(val, is("My Title"));

我们也可以将它的值传入其他方法:

String val = app.label("title").get();
app.input("description").enterText("The title is: " + val.toLowerCase());

Modifiers 的用法

每个 java API 的 action 方法,像 tap(),enterText(),都可以接受一个 map 形式的 modifiers 作为参数。Java API 提供一个 Mods 类来辅助生成该 map:

Map<String,String> mods = new Mods.Builder().timeout(3500).thinktime(1000).build();
Map<String,String> mods = Mods.of(Mods.TIMEOUT, "3500", Mods.THINKTIME, "1000");

如何生成报告

Java API 本身不支持生成报告,但 Junit 可以用 ant 等生成 xml 报告。对于自定义报告,MonkeyTalk Java API 提供了一些回调函数,供每个脚本开始或结束的时候调用。具体实现方法,我们可以通过重写一个 PlaybackListener 接口来实现:

private static StringBuilder report;

@BeforeClass
public static void beforeClass() throws IOException {
    mt = new MonkeyTalkDriver(new File("."), "iOS");
    mt.setThinktime(250);
    mt.setTimeout(5000);

    mt.setScriptListener(new PlaybackListener() {
        @Override
        public void onScriptStart(Scope scope) {
            //ignore
        }

        @Override
        public void onScriptComplete(Scope scope, PlaybackResult r) {
            //ignore
        }

        @Override
        public void onStart(Scope scope) {
            report.append(scope.getCurrentCommand());
        }

        @Override
        public void onComplete(Scope scope, Response resp) {
            report.append("--").append(resp.getStatus());
            if (resp.getMessage() != null) {
                report.append("[").append(resp.getMessage()).append("]");
            }
            report.append('\n');
        }

        @Override
        public void onPrint(String message) {
            //ignore
        }
    });

    report = new StringBuilder("---" + new Date() + "---\n");
}

@AfterClass
public static void afterClass() throws IOException {
    File rpt = new File("custom_report.txt");
    Writer out = new OutputStreamWriter(new FileOutputStream(rpt), "UTF-8");
    try {
        out.write(report.toString());
    } finally {
        out.close();
    }
}

Raw MonkeyTalk

Java API 还提供了一个 raw() 方法用来直接调用 MonkeyTalk 的命令:

app.raw("Button LOGIN Tap %timeout=123");

总结

上面简单的介绍了 Junit 中调用 MonkeyTalk Java API 进行测试的方法,以及介绍了一些 API 的用法。如果想要了解完整 API 的介绍和用法,请参考 MonkeyTalk Java API 的官方文档

共收到 7 条回复 时间 点赞

学习了。 MonkeyTalk 的 API 好强大。

不错啊

这个框架的能力挺强

谢谢分享

如何使得 monkeytalk 的脚本连续跑但相互不关联?@penghaibo203

这个没用过,改天回家,实验下= =,另外截图裂了,是不是我网速问题啊。

我这里图片也是裂的,求指导啊。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册