## 将你的iOS测试从UIAutomation(iOS 9.3及更低版本)迁移到 XCUITest(iOS 9.3及更高版本)
对于 iOS 自动化,Appium 依赖苹果提供的系统框架。对于 iOS 9.2及更低版本,苹果唯一的自动化技术被称为 UIAutomation,它运行在“Instruments”中。从 iOS 10开始,苹果已经完全删除了 UIAutomation 工具,因此 Appium 不可能按照以前的方式进行测试。同时,苹果推出了一款名为 XCUITest 的新型自动化技术,从 iOS 9.3到 iOS 10及以上版本,这将是苹果唯一支持的自动化框架。
Appium 从 Appium 1.6开始支持 XCUITest。在大多数情况下,XCUITest 的功能与 UIAutomation 的功能相匹配,因此,Appium 团队能够确保测试行为保持不变。这是使用 Appium 的好处之一!即使苹果完全改变了测试使用的技术,你的脚本可以保持大致相同!话虽如此,如果您想在 XCUITest 运行它们,还是存在些许差异,您需要关注测试脚本中需要修改的部分。本文将帮助您解决这些差异。
### 元素类名称模式
在 XCUITest 中,苹果已经为构成视图层次结构的 UI 元素提供了不同的类名。例如,`UIAButton` 现在为 `XCUIElementTypeButton`。多数情况下,这两个类之间可以直接映射。如果您使用 `class name` 定位器策略来查找元素,Appium 1.6将为您重写选择器。同样,如果你使用xpath定位器策略,Appium 1.6将在 XPath 字符串中找到所有 `UIA*` 元素,并适当地重写它们。
但是,这并不能保证你的测试可以完全相同地运行,原因有两个:
1. Appium 通过 XCUITest 和 UIAutomation 看到的应用的层次结构不一定是相同的。如果你有基于路径的 XPath 选择器,则可能需要进行调整。
2. 类名列表也不完全一样。许多由 XCUITest 返回的元素属于 `XCUIElementTypeOther` 类,这是一种通用的容器。
### 页面源码
如上述,如果你依赖 `page source` 命令返回的 app 源 XML,那么这个输出的 XML 与基于 UIAutomation 的结果会有显著不同。
### `-ios uiautomation` 定位策略
此定位器策略专门用于 UIAutomation,因此它不包括在 XCUITest 中。在即将发布的版本中,我们将致力于类似的“native”型定位策略。
### `xpath` 定位策略
1. 尽量不要使用 XPath 定位器,除非你完全没有其他选择。通常,xpath 定位器可能比其他类型的定位器慢,比如 accessibility id,class name 和 predicate (在某些特殊情况下可减缓100倍)。它们太慢了,因为 xpath 定位不是苹果的 XCTest 框架本身所支持的。
2. 使用
```
driver.findElement(x)
```
而不是使用
```
driver.findElements(x)[0]
```
通过xpath查找单个元素。您的定位器匹配的UI元素越多,你的脚本越慢。
3. 在通过 xpath 定位元素时,一定要使用非常具体的xpath。像这样的定位器
```
//*
```
可能需要几分钟才能完成,具体取决于您的应用程序有多少用户界面元素(例如,
```
driver.findElement(By.xpath("//XCUIElementTypeButton[@value='blabla']"))
```
比
```
driver.findElement(By.xpath("//*[@value='blabla']"))
```
或
```
driver.findElement(By.xpath("//XCUIElementTypeButton")))
```
要快很多。
4. 在大多数情况下,执行多个嵌套的 findElement 调用比执行 xpath 单个调用更快(例如,
```
driver.findElement(x).findElement(y)
```
通常比
```
driver.findElement(z)
```
要快
其中x和y不是xpath定位符,z是xpath定位符)。
### 系统依赖
除了升级 XCode 会带来(与Appium无关)许多问题之外,Appium 对 XCUITest 的支持还需要一个新的系统依赖:[Carthage](https://github.com/Carthage/Carthage)。Appium Doctor 现已更新,以确保`carthage`二进制在你的系统路径里。
### API差异
不幸的是,XCUITest API 和 UIAutomation API 还是有差别的。在许多情况下(比如 tap/click),行为是相同的,但一些功能在 UIAutomation 上可用,在 XCUITest 上并不可用。下面是已知的缺乏的功能:
* 地理位置支持(例如:`driver.location`)
* 振动设备
* 锁定设备
* 旋转设备(device _orientation_ 是支持的)
我们在努力把这些功能加到 Appium 的未来版本里。
#### 滚动和点击
在之前基于 UIAutomation 的驱动中,如果您尝试单击不在视图中的元素,UIAutomation 将自动滚动到该元素,然后点击它。但使用 XCUITest 时,不能这样处理。点击之前,你需要确保元素可见(与用户看到才能点击的行为一致)。
### 其他已知问题
最后,列出了初始1.6版本的已知问题(已解决的问题会被横线划去):
* <del>无法以横向模式与设备上的元素进行交互(https://github.com/appium/appium/issues/6994)</del>
* `shake`苹果不支持所以我们没有实现
* `lock`苹果不支持所以我们没有实现
* 设置地理位置不被苹果支持,我们也不支持
* 通过TouchAction/MultiAction API,`zoom`手势支持,因为苹果的一个bug,`pinch`手势不支持。
* <del>通过TouchAction/MultiAction API,`swipe`手势目前不受支持,应该很快解决(https://github.com/appium/appium/issues/7573)</del>
* <del>`autoAcceptAlerts`,`autoDismissAlerts`目前还不能工作,而且我们是否能够在将来实施这些,存在争议。</del>
* iOS SDK 有一个问题,因此使用某些 API 方法构建的 PickerWheels 不能由 XCUITest 自动执行。有关解决方法,请参阅 https://github.com/appium/appium/issues/6962,以确保您的 PickerWheels 正确构建。
我们将尽可能添加缺失的功能,并在以后的 Appium 版本中修复其他已知问题。
本文由 [校长](https://testerhome.com/xushizhao) 翻译,由 [lihuazhang](https://github.com/lihuazhang) 校验。
- 关于TesterHome和MTSC
- 关于Appium
- 简介
- Appium 客户端
- 入门指南
- 已支持的平台
- API 文档
- Appium驱动
- XCUITest (iOS)
- XCUITest Real Devices (iOS)
- UIAutomation (iOS)
- UIAutomation Safari Launcher (iOS)
- UIAutomator (Android)
- UIAutomator2 (Android)
- Espresso (Android)
- Windows
- Mac
- Appium命令
- Status
- Execute Mobile Command
- Session
- Create
- End
- Get Session Capabilities
- Go Back
- Screenshot
- Source
- Timeouts
- Timeouts
- Implicit Wait
- Async Script
- Orientation
- Get Orientation
- Set Orientation
- Geolocation
- Get Geolocation
- Set Geolocation
- Logs
- Get Log Types
- Get Logs
- Events
- Log event
- Get events
- Settings
- Update Settings
- Get Device Settings
- Settings
- Update Settings
- Get Device Settings
- Execute Driver Script
- Device
- Activity
- Start Activity
- Current Activity
- Current Package
- App
- Install App
- Is App Installed
- Launch App
- Background App
- Close App
- Reset App
- Remove App
- Activate App
- Terminate App
- Get App State
- Get App Strings
- End Test Coverage
- Clipboard
- Get Clipboard
- Set Clipboard
- Emulator
- Power AC
- Power Capacity
- Files
- Push File
- Pull File
- Pull Folder
- Interactions
- Shake
- Lock
- Unlock
- Is Locked
- Rotate
- Keys
- Press keycode
- Long press keycode
- Hide Keyboard
- Is Keyboard Shown
- Network
- Toggle Airplane Mode
- Toggle Data
- Toggle WiFi
- Toggle Location Services
- Send SMS
- GSM Call
- GSM Signal
- GSM Voice
- Network Speed
- Performance Data
- Get Performance Data
- Performance Data Types
- Screen Recording
- Start Screen Recording
- Stop Screen Recording
- Simulator
- Perform Touch ID
- Toggle Touch ID Enrollment
- System
- Open Notifications
- System Bars
- System Time
- Display density
- Authentication
- Finger Print
- Element
- Find Element
- Find Elements
- Actions
- Click
- Send Keys
- Clear
- Attributes
- Text
- Name
- Attribute
- Selected
- Enabled
- Displayed
- Location
- Size
- Rect
- CSS Property
- Location in View
- Other
- Submit
- Active Element
- Equals Element
- Context
- Get Context
- Get All Contexts
- Set Context
- Interactions
- Mouse
- Move To
- Click
- Double Click
- Button Down
- Button Up
- Touch
- Single Tap
- Double Tap
- Move
- Touch Down
- Touch Up
- Long Press
- Scroll
- Flick
- Multi Touch Perform
- Touch Perform
- W3C Actions
- Web
- Window
- Set Window
- Close Window
- Get Handle
- Get Handles
- Get Title
- Get Window Size
- Set Window Size
- Get Window Position
- Set Window Position
- Maximize Window
- Navigation
- Go to URL
- Get URL
- Back
- Forward
- Refresh
- Storage
- Get All Cookies
- Set Cookie
- Delete Cookie
- Delete All Cookies
- Frame
- Switch to Frame
- Switch to Parent Frame
- Execute Async
- Execute
- 编写 & 运行Appium脚本
- Running Tests
- Desired Capabilities
- The --default-capabilities flag
- Finding Elements
- Touch Actions
- CLI Arguments
- Server Security
- Web/Web Views
- Mobile Web Testing
- Automating Hybrid Apps
- Using ios-webkit-debug-proxy
- Using Chromedriver
- Image Comparison
- iOS
- Low-Level Insights on iOS Input Events
- XCUITest Mobile Gestures
- XCUITest Mobile App Management
- iOS Pasteboard Guide
- iOS Predicate Guide
- iOS Touch ID Guide
- iOS Install Certificate
- tvOS support
- Pushing/Pulling files
- Audio Capture
- Android
- Low-Level Insights on Android Input Events
- UiSelector Guide
- Espresso Datamatcher Guide
- Android Code Coverage Guide
- Activities Startup Troubleshooting Guide
- How To Execute Shell Commands On The Remote Device
- Android Device Screen Streaming
- How To Emulate IME Actions Generation
- How To Test Android App Bundle
- Other
- Reset Strategies
- Network Connection Guide
- Using Unicode with Appium
- Troubleshooting
- Tutorial
- Swipe Tutorial
- Screen
- Element
- Partial screen
- Simple
- Multiple scroll views
- Add scroll layout
- Tricks and Tips
- Screen
- Element
- Element search
- Fast
- Slow
- Guide
- 进阶概念
- 定位图像中的元素
- 使用定位元素的插件
- 迁移到 XCUITest
- 在 Appium 中使用 Selenium Grid
- Appium Logs Filtering
- 跨域 iframes
- 使用自定义 WDA 服务器
- 使用不同版本的 Xcode 运行
- The Event Timings API
- 并行测试的设置
- The Settings API
- Memory Collection
- 向Appium项目做贡献
- 从源代码运行 Appium
- 开发者概述
- 标准开发命令
- Appium 风格指南
- 如何编写文档
- Appium 包结构
- 鸣谢