在 iOS 移動應用程序上使用選擇器查找元素定位是我們在移動端 UI 自動化測試的先決條件。
但是,由於應用程序內容在原生 iOS 應用程序中的呈現方式,我們可以用來定位應用程序元素的選擇器與 Web 瀏覽器元素有很大不同。
在本文中,我們將了解 3 種常用方法來確定元素選擇器,以便在 iOS 應用程序中查找元素定位,進而用於進行自動化移動 UI 測試。
XCTest 框架和 Appium XCUITest 驅動程序
對於原生 iOS 應用,應用內容通過 WKWebView(iOS 8.0 或更高版本)呈現。Apple 開發的官方 XCTest 框架提供了一種方法,可以根據每個元素的渲染內容,根據其元素類型和 WKWebView 上下文中的元素屬性來定位元素。但是,XCTest 框架僅支持 Swift 和 Objective-C,因此當 iOS 應用程序是用 React Native 而不是 Swift 編寫時,它就不適用於移動端 UI 自動化測試了。
如果已經對於移動端 UI 自動化測試有所了解或應用的話,可能會對這樣一種替代方案有所耳聞: Appium XCUITest Driver(以前稱為 UIAutomation Driver for iOS)。 Appium XCUITest 驅動程序利用 Apple 的 XCTest 框架及其底層庫來提升 iOS 應用程序的自動化,並支持多種語言,包括 Java、Python、javascript、Ruby、C# 和 PHP。接下來將以 Appium XCUITest 驅動程序為例來看看我們如何檢查 iOS 應用程序並找到元素定位的。
查找 iOS 移動應用的元素選擇器
XCTest 框架或 Appium XCUITest 驅動程序提供了一種通過編程方式與 app 元素交互的方法,但我們仍然需要手動識別元素選擇器並將選擇器提供給我們的元素進行 UI 自動化測試。由於我們必須使用 iOS 模擬器或真實的 iOS 設備來打開應用程序,而設備上並沒有內置的檢查器來為我們提供這些信息,反觀在各種瀏覽器中,就有各種開發者工具可以用來提供這些信息。
以下是 3 種經常使用來檢查原生 iOS 應用程序內容並確定選擇器以定位元素的方法。
順便說一下,我們將用於演示的示例 iOS 應用程序如下。它使用 React Native 編寫並在 iOS 模擬器上運行。

(在 iOS 模擬器上運行的示例 react-native 應用程序的屏幕截圖)
1. driver.getPageSource()
Appium XCUITest 驅動程序提供了一種方法: getPageSource(),它可以在終端控制台中直接打印出當前呈現的應用頁面的頁面源代碼。這是一種可以快速查看應用頁面中所有元素的全貌,並確定可用於獲取元素定位的元素類型和屬性的快速方法。
只需要在 UI 自動化測試中插入以下代碼(如下Java代碼):
System.out.println(driver.getPageSource());
下面是示例應用程序的頁面源代碼片段。
<XCUIElementTypeOther type="XCUIElementTypeOther" name="Welcome to Example App" label="Welcome to Example App" enabled="true" visible="true" x="0" y="76" width="375" height="77"> <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="Welcome to Example App" name="Welcome to Example App" label="Welcome to Example App" enabled="true" visible="true" x="24" y="100" width="327" height="29"/> </XCUIElementTypeOther> <XCUIElementTypeOther type="XCUIElementTypeOther" name="Section One This is the description for Section One." label="Section One This is the description for Section One." enabled="true" visible="true" x="0" y="184" width="375" height="55"> <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="Section One" name="Section One" label="Section One" enabled="true" visible="true" x="24" y="184" width="327" height="25"/> <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="This is the description for Section One." name="This is the description for Section One." label="This is the description for Section One." enabled="true" visible="true" x="24" y="216" width="327" height="23"/> </XCUIElementTypeOther> <XCUIElementTypeOther type="XCUIElementTypeOther" name="Section Two This is the description for Section Two." label="Section Two This is the description for Section Two." enabled="true" visible="true" x="0" y="270" width="375" height="54"> <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="Section Two" name="Section Two" label="Section Two" enabled="true" visible="true" x="24" y="270" width="327" height="25"/> <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="This is the description for Section Two." name="This is the description for Section Two." label="This is the description for Section Two." enabled="true" visible="true" x="24" y="302" width="327" height="23"/> </XCUIElementTypeOther> <XCUIElementTypeOther type="XCUIElementTypeOther" name="Section Three This is the description for Section Three. Example Button" label="Section Three This is the description for Section Three. Example Button" enabled="true" visible="true" x="0" y="356" width="375" height="113"> <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="Section Three" name="Section Three" label="Section Three" enabled="true" visible="true" x="24" y="356" width="327" height="25"/> <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="This is the description for Section Three." name="This is the description for Section Three." label="This is the description for Section Three." enabled="true" visible="true" x="24" y="388" width="327" height="44"/> <XCUIElementTypeButton type="XCUIElementTypeButton" name="Example Button" label="Example Button" enabled="true" visible="true" x="24" y="431" width="327" height="38"/> </XCUIElementTypeOther>
可以看到,打印出來的頁面源代碼提供了每個元素的豐富信息,包括元素的類型和屬性等,我們可以使用這些信息來確定每個元素定位。
例如,對於 Example Button 按鈕元素,其頁面源代碼為:
<XCUIElementTypeButton type="XCUIElementTypeButton" name="Example Button" label="Example Button" enabled="true" visible="true" x="24" y="431" width="327" height="38"/> </XCUIElementTypeOther>
我們可以很容易地確定它的元素定位為:
driver.findElement(By.xpath("//XCUIElementTypeButton[@name='Example Button']"))
2. Accessibility Inspector
Accessibility Inspector是 Apple 開發的一個鮮為人知但非常有用的工具,可幫助開發人員提高 iOS 應用程序的可訪問性。該工具是與 Xcode 捆綁在一起的,因此需要在 Mac 電腦上安裝Xcode。Accessibility Inspector 通過解析和識別 iOS 應用程序上的每個元素並檢查元素的類型和可訪問性標簽來明確 iOS 應用程序的可訪問性功能及問題。由於它提供了有關應用程序上每個元素的詳細信息,因此它也可以很容易地用於在自動化 UI 測試中識別每個元素的選擇器。
下面是 Accessibility Inspector 為 Example Button 按鈕元素提供的信息:

(示例應用程序和輔助功能檢查器的屏幕截圖)
可以看到,Accessibility Inspector 顯示 Example Button 按鈕元素具有 Button 類型和 Example Button標簽,因此我們就可以使用它們來確定該元素定位:
driver.findElement(By.xpath("//XCUIElementTypeButton[@name='Example Button']"))
在確定確切的元素選擇器方面,Accessibility Inspector 一開始並不總是很容易使用,但是一旦熟悉了 Accessibility Inspector 如何呈現有關應用程序元素的信息,它將是一種快速且輕量級的工具,可以輕松完成工作。
實操示例:
1)Accessibility Inspector 在Xcode的入口:Xcode —— Open Developer Tool —— Accessibility Inspector

2)連接好設備后點擊開始按鈕即可開始使用。

3. Appium Desktop
Appium Desktop 是 Appium 團隊為 Mac、Windows 和 Linux 開發的桌面應用程序。它是許多 Appium 開發人員在移動端UI自動化測試中檢查 iOS 和 Android 應用程序元素的流行工具。
下面是 Appium Desktop 顯示的關於 Example Button 按鈕元素的內容:

(示例應用和 Appium 桌面的屏幕截圖)
可以看到,中間部分的 App Source 顯示了當前應用頁面的完整層次結構,右側部分的 Selected Element 顯示了詳細的信息和屬性列表 。更有用的是它還提供了用於定位當前元素的最佳選擇器,即 accessibility id 或者 xpath,這二者非常方便使用。
Appium Desktop 還提供了其他不錯的功能,例如直接單擊/點擊所選元素,以及在應用頁面更改后刷新頁面源。可以參考官方的
Appium Desktop代碼倉庫了解更多信息。
最后的話
總之,Appium Desktop 是一種用於檢查 iOS 應用程序上的元素獲取元素定位的流行且推薦的工具。如果你是剛開始編寫 UI 自動化測試,那么利用它來全面了解應用程序和頁面元素也很有用。一旦你相當熟悉了應用程序和頁面結構,直接在代碼中使用driver.getPageSource() 或使用 Accessibility Inspector 是快速找到元素定位的好選擇。
【Reference】
1、3 Ways to Find Element Selector for iOS App with Appium:
https://stephenweixu.com/blog/3-ways-to-find-element-selector-for-ios-app-with-appium
2、iOS 測試 WebDriverAgent 簡介:
https://testerhome.com/topics/4904 (WebDriverAgent Inspector 的使用)
3、Appium1.6 定位iOS元素和操作元素 :
https://www.cnblogs.com/meitian/p/7373460.html
4、Appium+Python3+iOS定位元素:
https://wangxiaoxi.cn/posts/appium-ios-2/ (元素定位慢的問題)
5、uiautomator2 使用Python測試 Android應用:
https://www.cnblogs.com/fnng/p/8486863.html (也有提到 這種方法可以獲取元素定位 )