## 將你的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 包結構
- 鳴謝