|
2#
楼主 |
发表于 2018-5-21 17:05:39
|
只看该作者
安装指南
同样,官方文档的快速开始也给出了详尽的步骤。但是实际上我在MAC上安装Appium的时候,还是遇到
了各种各样的坑。这个指南部分,希望能帮助大家趟过这些坑。
0.下载图形化桌面应用 Appium App
目前更新到1.5,不支持Xcode8 和UITest。如果还在使用Xcode 7系列的版本可以直接下载使用。
1.安装 homebrew & node 如果接触过web前端的同学应该不会陌生。
2.node安装appium
npm install -g appium
到这里需要挂代理翻墙。如果没有条件的话,可以使用淘宝的NPM 镜像。
安装到一半,应该会遇到/usr/local目录权限问题。这里给个小提示,建议给/usr/local/lib/node_modules/a
ppium开全权限sudo chmod -R 777 ./ ,不建议使用sudo,据说会遇到别的问题。如果中途遇到错误,使用
npm uninstall -g appium
命令卸载,然后重装。如果卸载不了,就直接去Finder/usr/local/lib/node_modules/appium目录删除就好了。
安装好之后,运行
$ appium &
命令就可以启动Appium的server了。
Hello World!
安装好了Appium server之后,可以开始运行第一个程序了。去官网下载示例代码。下载之后你能看到有
一个apps的文件夹和examples文件夹,前者放的是示例程序,后面是不同语言客户端的测试脚本。打开
apps/TestApp,运行能看到这是一个单页面的程序,最上方有两个输入框,输入数字,点击Compute Su
m按钮,就能得出两者相加的和。
下面我们就来做这个部分的UI自动化测试。找一个自己熟悉的Client语言去执行自动化脚本,比如Java。
打开,是一个Maven工程,下载了相应依赖库。之后打开SimpleTest文件,因为Xcode 8不支持UIAuto
mation框架,所以需要在setup中指定capability方式为XCUItest。
capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "XCUITest");
capabilities.setCapability("platformVersion", "10.0");
capabilities.setCapability("deviceName", "iPhone 6");
运行testUIComputation方法。可以看到模拟器启动了,但是之后会遇到Carthage找不到的问题
[XCUITest] Carthage not found. Install using brew install carthage
装上之后
Original error: Command '/bin/bash Scripts/bootstrap.sh -d'
官方Issues中找到了答案,WebDriverAgent缺少webpack。使用npm i -g webpack安装就好。PS:和
之前一样使用淘宝源或者挂一个代理。
完成了以上步骤之后,你就能看到你的Test在模拟器中自动运行,随着Terminal大量的log输出,测试
结果也成功返回到Java的Client,在IDEA中看到执行结果,PASS!到此为止,第一个自动化测试被执
行成功了~
截图留念
Client - Server - Device交互
driver.findElements
我们以java代码driver.findElements(By.className("UIATextField"))找到textField数组的过程为例子,去分
析一下log,看看一次交互式怎么进行的。
// client ----http----> server
[HTTP] --> POST /wd/hub/session/94f7526c-94ba-4ece-8740-d94bd3d4f50f/elements {"using":"class n
ame","value":"UIATextField"}
[MJSONWP] Calling AppiumDriver.findElements() with args: ["class name","UIATextField","94f7526c-94
ba-4ece-8740-d94bd3d4f50f"]
[debug] [XCUITest] Executing command 'findElements'
[debug] [BaseDriver] Valid locator strategies for this request: xpath, id, name, class name, -ios predicat
e string, accessibility id
[XCUITest] Rewrote incoming selector from 'UIATextField' to 'XCUIElementTypeTextField' to match XCUI
type. You should consider updating your tests to use the new selectors directly
[debug] [BaseDriver] Waiting up to 0 ms for condition
// server ----http----> device
[JSONWP Proxy] Proxying [POST /elements] to [POST http://localhost:8100/session/79CBBB84-DB6E-
48BA-B79F-91539E1E4708/elements] with body: {"using":"class name","value":"XCUIElementTypeTe
xtField"}
// device ----http----> server
[JSONWP Proxy] Got response with status 200: {"value":[{"ELEMENT":"1A29AE60-5433-4B52-83F8-
B4E2C794972E","type":"XCUIElementTypeTextField","label":"TextField1"},{"ELEMENT":"575EE2C2-4
AFF-4320-B4D0-C30F59410DA9","type":"XCUIElementTypeTextField","label":"TextField2"}],"sessionI
d":"79CBBB84-DB6E-48BA-B79F-91539E1E4708","status":0}
[MJSONWP] Responding to client with driver.findElements() result: [{"ELEMENT":"1A29AE60-5433-4
B52-83F8-B4E2C794972E","type":"XCUIElementTypeTextField","label":"TextField1"},{"ELEMENT":"
575EE2C2-4AFF-4320-B4D0-C30F59410DA9","type":"XCUIElementTypeTextField","label":"TextField
2"}]
// server ----http----> client
[HTTP] <-- POST /wd/hub/session/94f7526c-94ba-4ece-8740-d94bd3d4f50f/elements 200 225 ms
- 285
其中
[MJSONWP] 打印的是S内部的处理日志。
[JSONWP Proxy] 打印的是S/D之间的通信日志。
可以看到,Client、Server、Device是通过Http协议通信的,大致流程为:
Client通过http协议,将指定格式的命令发送给server。server调用中间层AppiumDriver解析命令,发
送给实际的处理者。实际处理者依据平台、版本不同而不一样,这里是XCUITest(iOS)。而Device
(iphone、模拟器)和Server的通讯也是通过http协议。
到这里,大家会有疑问了,Server怎么找到对应的Device,他们之间如何通过Http通讯的?这里就要
引出WebDriverAgent。它的作用:
WebDriverAgent 在 iOS 端实现了一个 WebDriver server ,借助这个 server 我们可以远程控制 iOS 设
备。
参考
WDA的inspector演示:直接在浏览器端打开 http://192.168.0.105:8100/inspector
TextField赋值
再看TextField赋值java代码elem.sendKeys(String.valueOf(rndNum));的执行步骤
[HTTP] --> POST /wd/hub/session/94f7526c-94ba-4ece-8740-d94bd3d4f50f/element/1A29AE60-54
33-4B52-83F8-B4E2C794972E/value {"id":"1A29AE60-5433-4B52-83F8-B4E2C794972E","value":["1"]}
[MJSONWP] Calling AppiumDriver.setValue() with args: [["1"],"1A29AE60-5433-4B52-83F8-B4E2C79
4972E","94f7526c-94ba-4ece-8740-d94bd3d4f50f"]
[debug] [XCUITest] Executing command 'setValue'
[JSONWP Proxy] Proxying [GET /element/1A29AE60-5433-4B52-83F8-B4E2C794972E/attribute/typ
e] to [GET http://localhost:8100/session/79CBBB84-DB6E-48BA-B79F-91539E1E4708/element/1A29
AE60-5433-4B52-83F8-B4E2C794972E/attribute/type] with no body
[JSONWP Proxy] Got response with status 200: "{\n \"value\" : \"XCUIElementTypeTextField\",\n \"s
essionId\" : \"79CBBB84-DB6E-48BA-B79F-91539E1E4708\",\n \"status\" : 0\n}"
[debug] [BaseDriver] Set implicit wait to 0ms
[debug] [BaseDriver] Waiting up to 0 ms for condition
[JSONWP Proxy] Proxying [POST /element] to [POST http://localhost:8100/session/79CBBB84-DB6E-
48BA-B79F-91539E1E4708/element] with body: {"using":"class name","value":"XCUIElementTypeKey
board"}
[JSONWP Proxy] Got response with status 200: {"value":{"using":"class name","value":"XCUIElement
TypeKeyboard","description":"unable to find an element"},"sessionId":"79CBBB84-DB6E-48BA-B79F-91
539E1E4708","status":7}
[debug] [XCUITest] No keyboard found. Clicking element to open it.
[JSONWP Proxy] Proxying [POST /element/1A29AE60-5433-4B52-83F8-B4E2C794972E/click] to [PO
ST http://localhost:8100/session/79CBBB84-DB6E-48BA-B79F-91539E1E4708/element/1A29AE60-543
3-4B52-83F8-B4E2C794972E/click] with body: {}
[JSONWP Proxy] Got response with status 200: {"status":0,"id":"1A29AE60-5433-4B52-83F8-B4E2C79
4972E","value":"","sessionId":"79CBBB84-DB6E-48BA-B79F-91539E1E4708"}
[debug] [BaseDriver] Waiting up to 0 ms for condition
[JSONWP Proxy] Proxying [POST /element] to [POST http://localhost:8100/session/79CBBB84-DB6E-4
8BA-B79F-91539E1E4708/element] with body: {"using":"class name","value":"XCUIElementTypeKeyboard"}
[JSONWP Proxy] Got response with status 200: {"value":{"ELEMENT":"FB515A63-3249-419E-8106-26
81A1FEBA24","type":"XCUIElementTypeKeyboard","label":null},"sessionId":"79CBBB84-DB6E-48BA-B7
9F-91539E1E4708","status":0}
[debug] [BaseDriver] Set implicit wait to 0ms
[JSONWP Proxy] Proxying [POST /element/1A29AE60-5433-4B52-83F8-B4E2C794972E/value] to [PO
ST http://localhost:8100/session/79CBBB84-DB6E-48BA-B79F-91539E1E4708/element/1A29AE60-543
3-4B52-83F8-B4E2C794972E/value] with body: {"value":["1"]}
[JSONWP Proxy] Got response with status 200: {"status":0,"id":"1A29AE60-5433-4B52-83F8-B4E2C79
4972E","value":"","sessionId":"79CBBB84-DB6E-48BA-B79F-91539E1E4708"}
[MJSONWP] Responding to client with driver.setValue() result: null
[HTTP] <-- POST /wd/hub/session/94f7526c-94ba-4ece-8740-d94bd3d4f50f/element/1A29AE60-5433-
4B52-83F8-B4E2C794972E/value 200 2247 ms - 76
|
|