以下内容转载自我的云栖社区:https://yq.aliyun.com/users/1035573748035711
接触 Macaca 已经有一段时间,从开始的对于 UI 自动化的调研开始,将 Macaca 与 Appium,Robotium 等自动化方案进行了多方对比,最终 Macaca 脱颖而出成为团队的敲定方案,随后经历了 Macaca 从 JS 版本到 Java 版本的迭代,踩了很多坑,积累了很多经验教训,在这里总结沉淀一下,以方便后来人少走弯路,加快脚步。
Macaca 是一套基于 WebDriver 标准协议开发的开源自动化解决方案,旨在解决跨平台,跨终端的 UI 自动化测试的短板问题,减少繁杂、重复的人工工作,降低自动化测试的上手门坎。终端上,Macaca 同时支持 Native(iOS&&Android)、Hybrid、Mobile Web、以及 PC 端的自动化测试,用例编写上,Macaca 采取 CS 架构,可以支持任意编程语言的封装,目前已支持 Javascript、Java、Python 三种语言,感兴趣的同学甚至可以自行封装支持任意自己习惯的语言。目前,Macaca 在 testerHome 上的关注度以及活跃度都保持着强劲的势头,他不只提供了基础的用例编写功能,更提供了性能数据,包含电量、内存等指标的采集功能的附带模块,以及一套分布式持续集成系统供有需者选择,选择 Macaca 作为 UI 自动化的框架,将为大家提供很大的便利性。
这部分主要针对 Macaca1.0 版本环境配置进行介绍,Macaca 更新 2.0 后,环境配置上有些许改动,配置最新版 Macaca 环境,请略过本张姐,参考我的最新文章 从无到有搭建 Macaca 环境 (forMac)
https://github.com/macaca-sample/sample-java
官方 demo 已更新,如下描述为针对早前版本的描述,仅供参考。
通过 Eclipse 导入 Maven 工程,会发现工程结构相当简单,只有一个 SampleTest.java 类,之所以如此简洁,是因为 Demo 工程将 Macaca 的 Java 源码库以 Maven 源的形式配置到了 pom.xml 中:
<dependency>
<groupId>macaca.webdriver.client</groupId>
<artifactId>macacaclient</artifactId>
<version>1.0.1</version>
</dependency>
如上图,可知道当 Macaca 有更新时,可以通过修改上图中的 version 版本号来实现库的更新。
对 SampleTest.java 源码的分析:
*setUp() 方法主要用于配置被测应用的基础信息,包含平台版本,系统版本,安装包路径等,Demo 实例中提供的为一个 PC 端的实例,当配置移动端应用测试时,相关参数稍有不同,后面会给出对应移动端的 setUp() 配置
@Before
public void setUp() throws Exception {
// 在setUp()中配置被测应用的基础信息,如平台版本,安装包地址等
Logger logger = Logger.getLogger(getClass());
JSONObject porps = new JSONObject();
porps.put("autoAcceptAlerts", true);
porps.put("browserName", "electron");
porps.put("platformName", "desktop");
porps.put("version", "");
porps.put("javascriptEnabled", true);
porps.put("platform", "ANY");
JSONObject desiredCapabilities = new JSONObject();
desiredCapabilities.put("desiredCapabilities", porps);
driver.initDriver(desiredCapabilities).setWindowSize(1280, 800).get("https://www.baidu.com");
}
* 移动端的 setUp() 配置信息实例
@Before
public void setUp() throws Exception {
JSONObject porps = new JSONObject();
porps.put("autoAcceptAlerts", true);
porps.put("platformVersion", "9.3");
porps.put("deviceName", "iPhone 5s");
porps.put("platformName", "iOS");
// 指定待测应用的安装包
porps.put("app", "**/**/targetApp.zip");
// 指定app复用类型,比如需要每次用例启动重装app,可以设置为1,不重装,可以设为3
porps.put("reuse",1);
JSONObject desiredCapabilities = new JSONObject();
desiredCapabilities.put("desiredCapabilities", porps);
driver.initDriver(desiredCapabilities);
driver.platform = "ios";
}
针对如上代码,需要注意的是,对于 iOS 平台,在模拟器上跑用例时 app 的安装包需要基于.app 包压缩后的 zip 包 (这个.app 包可以找对应的 iOS 开发同学提供,在 XCode 工程目录下 Products 目录下),而不能用.ipa 包进行压缩,对于真机,可以直接使用.ipa 文件,不过需要涉及证书签名等问题,关于这个,可参考https://testerhome.com/topics/6503。
另外,对于配置参数,iOS 与安卓有各自特有的参数,具体配置信息可参考:
https://macacajs.com/helpful-settings
滑动到此页面底部可看到 Desired Capabilities
* 测试用例编写
@Test
public void test_case_1() throws Exception {
driver
.elementById("kw")
.sendKeys("macaca")
.sleep(1000)
.elementById("su")
.click()
.sleep(3000);
String html = driver.source();
Assert.assertThat(html, containsString("<html>"));
driver
.elementByCss("#head > div.head_wrapper")
.elementByXPath("//*[@id=\"kw\"]")
.sendKeys(" elementByXPath")
.elementById("su")
.click()
.takeScreenshot();
}
可能习惯 Java 的同学对于测试用例的这种链式写法有些不习惯,个人认为这样写与 Javascript 版本的迁移有所关联,优势在于可以便利的实现连续的 UI 操作,而不用一行行写重复样式的调用,而实现这种语法的关键在于源码中每一个接口,比如 elementById(),sendKeys() 都返回了 driver 本身,如下:
#MacacaClient.java
/**
* Search for an element on the page, starting from the document root.
* @param elementId The ID attribute of element
* @return The currently instance of MacacaClient
* @throws Exception
*/
public MacacaClient elementById(String elementId) throws Exception {
JSONObject jsonObject = new JSONObject();
jsonObject.put("value", elementId);
jsonObject.put("using", "id");
element.findElement(jsonObject);
return this;
}
以上源码来自于 Java 版 Source Code:https://github.com/macacajs/wd.java
同 Javascript 版用例不同的一点是,Javascript 版本的用例可以直接通过一条命令启动 macaca server 并运行 case,而 Java 版的用例则需要单独启动 Macaca server,然后执行测试用例,具体操作如下:
$cd path/to/macaca-test-sample-java
$macaca server --verbose
如果想查看启动中的详细信息 可以追加--verbose 参数 $macaca server --verbose
$mvn -s settings.xml clean install -Dmaven.test.skip=true
注:mvn -s 的作用在于使 maven 以工程目录下的 settings.xml 文件为依据下载依赖,但是实践中发现部分同学会出现 mvn -s 无法生效的作用,这样会导致依赖下载失败,这种情况下,需要大家将工程目录下的 settings.xml 中的配置相应的添加到本地 settings 中。
$mvn test
或者可以直接进入到 IDE 中运行 test 用例
这样就可以看到自动执行的测试效果了
实际应用中自动化用例的编写很多情况下都是查找控件并操作,于是如何快速高效的查找控件成为了一件关乎效率的大问题,最早的时候对于安卓,查找控件依赖于 Android 自带的 UIAutomator viewer 工具,iOS 则依赖于 XCode 中的 Accessibility Inspector 工具,但是这两种工具查找起来相对麻烦,效率相对低下,针对这个问题,Macaca 团队提供了统一的 Inspector 工具,可以以 Web 的方式方便的查看不论是安卓还是 iOS 的控件。
具体使用链接如下:https://macacajs.com/inspector
关于控件的查找另外补充一点,目前 Java 版提供通过 id,css,name,xpath 等方式获取控件,但 xpath 的方式扩展性太弱,不到万不得已不推荐使用,最好的方式是希望对每个控件能有一个唯一性的 id 标示获取,但这需要开发同学的配合,对于安卓,有一些控件是有 id 的,因为开发同学自身也需要定位这个控件,但对于 iOS,有很多控件是不存在 id 的,但是如果有一种底层的方案,按照一定的规则给控件自动增加 id 属性,则只需要在底层做一定适配而不需要开发同学额外给每个控件增加 id 属性,这对于提高自动化的效率大有裨益,在网上找到了一篇类似思想的文章,仅供参考:为 UIAutomation 添加自动化测试标签的探索
启动 server :
//--verbose为可选参数,用于查看详细日志,可不加
$macaca server --verbose
查看当前设备 ID:
Android:
$adb devices
iOS:
$xcrun simctl list
查看视图 Dom 树
//***部分为要监控的设备id
$ app-inspector -u ***
前提是要安装了 app-inspector ,安装命令:
cnpm i app-inspector -g
官方教程包含环境搭建/API 参考(Js、Java、Python)/CI 集成等最权威的指南,参考首选。
testerHome 上包含很多实际应用的帖子,很多步骤介绍的比较详细并配有截图,以及暴露了很多开发者使用过程中的坑,对于扫盲非常有帮助
想深入了解 Macaca 原理的同学可以研究 Macaca 的源码,Macaca 团队将每个模块单独建立了代码库,看起来清楚明了。如果在开发中遇到了框架层面的问题,也可以在对应的 github 上提 issue,甚至可以提交 PR 参与到 Macaca 的共建中,作为开源框架,Macaca 需要大家共同努力发扬光大。
“Macaca 开源社区” 群的钉钉群号: 11775486(欢迎入群讨论,钉钉顶部搜索框搜索群号加入即可)
UI 自动化框架调研总结
从无到有搭建 Macaca 环境 (forMac)
Macaca-Java 版入门指南
UI 自动化 Macaca-Java 版实践心得
UI 自动化利器 - 为你的应用自动添加控件 ID 探索
Macaca 基础原理浅析