##Macaca
macaca 是阿里开源的基于 Node.js 开发的自动化测试工具,支持 native,hybird,moblie web,关于 macaca 具体的内容参见官网macaca.
macaca 是如何驱动自动化测试的呢?事实上 macaca 和 appium 在架构和一些应用层面有很多相似的地方。
作为client
的我们可以使用不同语言去编写测试脚本,其中测试脚本遵循webdriver
协议,client
向测试框架启动的server
发送http
请求。正因为client
和server
是基于http
进行通讯的,因此client
可以支持不同的编程语言。server
通过解析HTTP
的request
,然后调用IOS
提供的UIAutomation
库来进行模拟点击等的操作,操作完成后移动设备会将操作结果返回给server
,然后server
将这个操作结果返回给client
。
👆有提到过webdriver
协议:
其实它就是一层基础的协议规范。正是因为这样的协议存在一些自动化测试框架可以使用多种语言编写测试脚本。它提供了web
页面操作的相关规范,比如元素的定位,浏览器原生事件的操作,还有获取DOM
元素属性等一系列的方法。不管你用什么语言编写测试脚本的话,都应该按照这个协议规范来。WebDriver
通过原生浏览器支持或者浏览器扩展直接控制浏览器。WebDriver
针对各个浏览器而开发,取代了嵌入到被测 Web
应用中的 JavaScript
。与浏览器的紧密集成支持创建更高级的测试,避免了JavaScript
安全模型导致的限制。除了来自浏览器厂商的支持,WebDriver
还利用操作系统级的调用模拟用户输入。webDriver
支持了所有的主流浏览器,同时还支持了Iphone
和Android
的移动应用测试。
接下来就带着大家一步一步使用 macaca 进行进行自动化测试:
###step 1
全局安装macaca
的cli
,如果觉得比较慢,就换淘宝的cnpm
镜像吧。
npm install macaca -g
安装完成后可以输入
//查看cli的提供其他的功能
macaca -h
//用以查看当前的环境配置
macaca doctor
//用以单独启动一个webdriver server
macaca server
//启动测试
macaca run
现在输入macaca doctor
:
在Android checklist
里面出现了 2 条红色的提示文案,说明这 2 个选项没有配置完成。我现在是以IOS
为例,暂且不管这 2 个和Andriod
相关的配置。不清楚的可以google
。其中在IOS checklist
当中:出现了Xcode
和ios_webkit_debug_proxy
.
首先你需要通过app store
安装Xcode
。全局安装ios_webkit_debug_proxy
这个包,这个包用于测试 ios 的 webview:
brew install ios-webkit-debug-proxy
此外,还需要全局安装ios-driver
:
npm i macaca-ios -g
这样准备好了基础的测试套件。接下来你可以克隆macaca
提供的官方示例,其中包括 IOS 的 app 和相关的测试脚本,对照着官文文档感受下大致的流程:
git clone https://github.com/macacajs/macaca-test-sample.git --depth=1
接下来进行自己的测试工作:
因为我是前端开发人员,要测试native
里面的webview
。首先让 IOS 的同学帮忙打包一个.app
格式的应用,并压成zip格式
的文件。PS:打包的时候选用debug模式
。
准备好了原材料,先让我们停一停。做UI测试
的话,要模拟用户各种操作,那么必须得知道native
应用上不同界面的元素,就像获取html
里面的DOM
节点一样。因为 macaca 提供了通过Xpath
去获取native
页面上不同的元素节点的API
。因此可以通过这种方式。
macaca
提供了app-inspector
这样一个使用树状态结构查看UI
布局,自动生成XPath
的工具。
npm install app-inspector -g
安装完成后,通过macaca-cli
启动你的IOS模拟器
,运行你的应用。
然后通过app-inspector
启动UI
检测工具,
app-inspector -u YOUR-DEVICE-ID
获取uuid
的方式:
命令行输入:
xcrun simctl list
这行命令会列出你的所以模拟器信息,里面有类似 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
的代码,就是模拟器UDID
,选择当前模拟器状态是Booted
的那个。
通过app-inspector
启动这个工具后,打开在Chrome
里面打开命令行里面提示的浏览器地址,这样在浏览器上就能看到在native
里面打开的ios
页面。
因为我要测试webview
的页面,因此native
的页面的所有元素节点通过app-inspector
这个工具去获取Xpath
,然后编写测试脚本模拟用户的操作,一步一步的进入到webview
页面。
在我测试的应用当中,从app
打开到进入要测试的webview
页面的测试脚本就变成了:
.waitForElementByXPath('//XCUIElementTypeApplication[1]/XCUIElementTypeWindow[1]/XCUIElementTypeOther[2]/XCUIElementTypeButton[1]')
.click()
//用户名输入
.waitForElementByXPath('//XCUIElementTypeApplication[1]/XCUIElementTypeWindow[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeTextField[1]')
.sendKeys(username)
//密码输入
.waitForElementByXPath('//XCUIElementTypeApplication[1]/XCUIElementTypeWindow[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[3]/XCUIElementTypeSecureTextField[1]')
.sendKeys(password)
.sendKeys('\n')
//登录按钮
.waitForElementByXPath('//XCUIElementTypeApplication[1]/XCUIElementTypeWindow[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeButton[2]')
.click()
//更多按钮
.waitForElementByXPath('//XCUIElementTypeApplication[1]/XCUIElementTypeWindow[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeImage[1]/XCUIElementTypeButton[2]')
.click()
.sleep(1000)
.swipe(200, 400, 200, 100, 500)
.waitForElementByXPath('//XCUIElementTypeApplication[1]/XCUIElementTypeWindow[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeCollectionView[1]/XCUIElementTypeCell[10]')
.click()
.sleep(1000)
.waitForElementByXPath('//XCUIElementTypeApplication[1]/XCUIElementTypeWindow[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]/XCUIElementTypeScrollView[1]/XCUIElementTypeOther[2]')
.click()
.sleep(1000)
这样完成了native
进入到webview
页面的所有操作。
接下来就是webview
的模拟操作啦。放到下一节来讲吧。