ps:有沒有人和我一樣覺得Appium官方文檔寫的很爛的, 這官方文檔,還不如很多人寫的博客詳細,而且對於初學的入門者實在是不夠友好,
官網:https://github.com/appium/java-client
移動測試神器:帶你玩轉Appium
移動測試神器:帶你玩轉Appium
以移動應用的自動化測試為主題,介紹目前主流的移動應用自動化測試框架 Appium。Appium 是一個開源的自動化測試框架,支持 iOS 和 Android 上 Web App、Native App 和 Hybrid App 的自動化測試。
由於基於 Appium 的移動應用環境搭建相對復雜,雖然網上也有不少教程,但是知識點都比較零碎,而且大多都是基於早期版本的示例,所以我會使用最新版本的 Appium Desktop 1.6.2 和 Appium Server 1.8.1 來展開今天的內容:
- 首先,我會展示如何在 Mac 環境下一步一步地搭建 Appium 測試環境;
- 接下來,我以 iOS 為例,實際開發兩個測試用例,一個是 Native App 的測試用例,另一個是 Web App 的測試用例(因為 Hybird App 的測試用例其實是類似的,Native App 的殼,Web App 的內容,所以就不再單獨舉例子了);
- 然后,我會在 iOS 的模擬器上實際執行這兩個測試用例(之所以選擇 iOS 模擬器,而不用 iOS 真機做例子,是因為 iOS 真機的測試需要用到 Apple 開發者賬號,還需要對被測應用進行簽名等,會在環境搭建過程中引入很多額外步驟,而這些步驟對於講解 Appium 並沒有直接的關系);
- 最后,當你已經通過實際使用對 Appium 形成感性認識后,我再來簡單介紹一下 Appium 的內部原理,讓你做到知其然知其所以然。
移動應用的自動化測試需求
在開始設計測試用例前,我們首先需要明確要開發的這兩個自動化測試用例的具體測試需求。
- Native App 的測試用例,被測 App 我選用了 Appium 官方的示例 App,被測 App 的源代碼可以通過“https://github.com/appium/ios-test-app” 下載,然后在 Xcode 中編譯打包成 TestApp.app。
具體的測試需求是輸入兩個數字,然后點擊“Compute Sum”驗證兩個數字相加后的結果是否正確。 - Web App 的測試用例,具體需求是在 iPhone 上打開 Safari 瀏覽器,訪問 Appium 的官方主頁“http://appium.io”,然后驗證主頁的標題是否是“Appium: Mobile App Automation Made Awesome”。
圖 1 Native App 和 Web App 的 GUI 界面示例
接下來,我將從最初的環境搭建開始,和你來一起開發 iOS 上的 Native App 和 Web App 的測試用例。首先我們看一下 iOS 的環境搭建,如果你之前沒有接觸過這部分內容,你可以跟着我的步驟一步一步來做;而如果你已經比較熟悉 Xcode 的話,可以跳過這部分內容,直接從“Appium 環境搭建”部分看起。
iOS 環境搭建
在正式搭建 Appium 環境前,我們先來搭建 iOS 開發環境:
- 首先,下載安裝 Xcode;
- 然后,在 Xcode 中下載 iOS 的模擬器;
- 接着,使用 Xcode 編譯打包被測試 App;
- 最后,在 iOS 的模擬器中嘗試手工執行這兩個測試用例。
在 iOS 模擬器中,手動執行測試用例的具體操作步驟如下:
- 啟動 Xcode,導入 ios-test-app 下的 TestApp.xcodeproj 項目。
- 在 Xcode 中,打開“Preferences”中的“Components”,完成 iOS 10.0 Simulator 的下載。
- 在 Xcode 的“General”頁面,將 TestApp 的“Deployment Target”設置為 10.0,並且將“Devices”設置為“iPhone”,如圖 2 所示。
圖 2 TestApp 的 General 配置
- 在 Xcode 中編譯運行 TestApp,之后系統會自動啟動 iPhone 模擬器,自動完成 TestApp 的安裝,並在 iPhone 模擬器中自動啟動 TestApp。
- 在 TestApp 中手動執行自定義的加法測試用例。
- 退出 TestApp,然后打開 Safari 瀏覽器,在 Safari 中執行訪問 Appium 官方主頁的測試用例。
至此,你已經搭建好了 iOS 開發環境,並且成功編譯打包了 TestApp。接下來,我們再一起來搭建 Appium 測試環境,並嘗試在 Appium 中開發上述的兩個測試用例。
Appium 測試環境搭建
通過 Appium 的官方網站下載並安裝最新版本的 Appium,截止本文寫作的時間,最新版本是 Appium-1.6.2.dmg。
需要注意的是,早期版本和網上很多教程都建議用命令行的形式啟動 Appium Server,但在這里我是想強調的是,你完全可以通過界面啟動(在 Launchpad 中找到 Appium 的圖標,點擊即可啟動),而且新版本的 Appium 也推薦這個啟動方式。通過界面啟動,是目前最簡單直接的方式。
然后,你需要用命令行“npm install -g appium-doctor”安裝 Appium 的環境診斷工具 appium-doctor,用於檢查 Appium 所依賴的相關環境變量以及其他安裝包是否都已經配置好了。如果還沒有,就需要逐個安裝,並根據 appium-doctor 的提示配置環境變量。
這里,Appium 最主要的依賴項主要有:Java、Node.js、Xcode、Carthage、Android SDK、adb 等。如果你所有的環境依賴都正常配置的話,你就會看到 appium-doctor 返回這樣一個截圖,如圖 3 所示。
圖 3 正常配置環境依賴后,appium-doctor 返回的截圖
按照上面的步驟,配置好 Appium 的環境依賴后,就可以繼續啟動 Appium Server 了。
Appium Inspector 的使用
為了后續測試用例的順利執行,我們可以先來熟悉一下 Appium Inspector 的使用。Appium Inspector 主要是用來協助對界面元素進行定位的工具。
首先,我們來看看如何使用 Appium Inspector 啟動 iPhone 的模擬器,並在模擬器上運行 TestApp,以及如何通過 Inspector 定位 TestApp 界面上的元素(了解元素的定位是后續開發自動化腳本的基礎)。具體的操作過程如下。
- 通過 Appium Server 的“Start Inspector Session”按鈕,進入 Session 配置界面。
圖 4 點擊“Start Inspector Session”按鈕打開 Session 配置界面
- 在 Session 配置界面完成必要參數的配置。這里你需要根據選用的移動設備操作系統、模擬器 / 真機等具體情況來完成參數配置工作。需要配置的參數主要包括:platformName、platformVersion、DeviceName、automationName 和 app。
其中,automationName,指自動化測試框架的名稱,這里采用了 XCUITest;app 指被測 Native App 的安裝包路徑,這里使用之前 Xcode 打包生成的 TestApp.app,這樣啟動模擬器時,就會自動把 TestApp.app 安裝到模擬器中。
其他參數的配置非常簡單,我就不再一一展開了。
圖 5 Session 配置界面
- 完成配置后,點擊 Session 界面的“Start Session”按鈕,啟動 iPhone 模擬器,並在 iPhone 模擬器中啟動 TestApp,同時還會打開 Inspector 窗口。如圖 6 所示。
圖 6 啟動 Session 后的 Inspector 窗口
- 在 Inspector 窗口,我們可以利用“Select Elements”功能,通過點擊元素顯示 Native App 上的元素定位信息。如圖 7 所示。
圖 7 “Select Elements”功能示例
- 在 Inspector 窗口,可以通過“Recording”功能生成不同語言的自動化腳本。比如在啟用了“Recording”功能后,點擊“Compute Sum”按鈕,就會生成如圖 8 所示的自動化腳本片段。
圖 8 “Recording”功能示例
了解了如何通過 Inspector 獲取元素定位信息的方法之后,我們就來正式開發基於 Appium 的第一個 Web App 和第一個 Native App 的測試用例。
基於 Appium 開發你的第一個 Native App 的測試用例
第一步,建立一個空的 Maven 項目,然后在 POM 文件中加入如圖 9 所示的依賴。
在這個案例里面,我們會使用 TestNG 組織測試用例,所以代碼的第 14 行加入了 TestNG 的依賴。
第 19 行的 java-client 是關鍵,java-client 的作用是利用 Java 代碼將測試用例中的操作步驟發送給 Appium Server,然后由 Appium Server 自動完成這些操作。
目前 Appium 支持多種編程語言,每種語言都有自己的 client,比如這里使用 Java 語言,所以引入了 java-client;如果你使用 Python 語言,那么就需要引用 python-client。
圖 9 POM 文件加入 TestNG 和 java-client 的依賴
第二步,創建一個類,並命名為“iOS_NativeApp_DemoTest”,然后按照如圖 10 所示的代碼實現這個 class。
注意,這里的代碼是真實的可執行 Java 代碼,你可以直接拿去使用。
圖 10 Native App 測試用例實例
- 代碼第 21 行的 @BeforeTest,第 38 行的 @AfterTest,以及第 44 行的 @Test,都是利用了 TestNG 的 annotation 對函數進行標注。
標有 @Test 的函數是真正的測試主體,所有測試相關的步驟都放在這個函數中;
標有 @ BeforeTest 的函數會在 @Test 函數之前執行測試的相關准備工作,圖中的代碼用這個函數完成了 DesiredCapabilities 的設置,並用該 Capabilities 構造了 iosdriver;
標有 @ AfterTest 的函數在 @Test 函數執行結束后執行,主要用於環境的清理和收尾,圖示的代碼用這個函數完成了 iosdriver 的退出操作。 - 代碼的第 24-33 行構造了 DesiredCapabilities 對象,並對 APPIUM_VERSION、PLATFORM_VERSION、PLATFORM_NAME、AUTOMATION_NAME、DEVICE_NAME 和 APP 等參數進行了設置。其中 APP 的值是被測 Native App 安裝包的絕對路徑。
- 代碼的第 46-58 行是測試用例的主體部分,主要分為三部分:
第 47-50 行通過 iosdriver 的 findElementByAccessibilityId 方法定義了頁面上的四個元素,分別是輸入參數框 A、輸入參數框 B、計算按鈕和加法結果顯示框。代碼中具體的 AccessibilityId 可以通過 Inspector 獲取。
第 53-55 行通過自定義元素的操作執行加法運算。
第 58 行通過斷言方法 assertEquals 驗證加法運算的結果。
第三步,為了運行這個 TestNG 的測試用例,我們需要再添加一個 testng.xml 文件, 具體內容如圖 11 所示。
圖 11 testng.xml 文件示例
第四步,在保證 Appium Server 已經啟動的情況下,就可以運行 testng.xml 執行測試了。 測試開始后,首先會自動啟動基於 iOS 10.0 的 iPhone 7 模擬器,然后依次自動完成 WebDriverAgent(WDA)和被測 Native App 的安裝。
WDA 是由 Facebook 開源的支持 iOS 自動化的代理工具,其底層通過 XCUItest 實現自動化。
接着,就會自動運行被測 Native App,並根據 @Test 函數中定義的步驟完成自動化測試的步驟和驗證。
到此,我們的第一個基於 Appium 的 Native App 自動化測試用例就設計完了。
基於 Appium 開發你的第一個 Web App 的測試用例
有了 Native App 測試用例的設計基礎,再來實現一個基於 Appium 的 Web App 自動化測試用例就簡單得多了。
第一步,在上述的 Maven 項目中再創建一個類,並命名為“iOS_WebApp_DemoTest”,然后按照如圖 12 所示的代碼實現這個類。
圖 12 Web App 測試用例實例
代碼的整體結構和上述 Native App 測試用例的完全一致,只有一個地方需要特別注意:代碼的第 29 行,由於 Web App 是基於瀏覽器的測試,所以這里不需要指定 App 這個參數,而是直接用 BROWSER_NAME 指定瀏覽器的名字即可。
對於測試用例的主體部分,也就是代碼的第 45-47 行就比較簡單了,首先打開 Safari 瀏覽器並訪問“http://appium.io/”,接着用斷言方法 assertEquals 驗證頁面的 Title 是不是“Appium: Mobile App Automation Made Awesome.”。其中,實際頁面的 Title,可以通過 mobiledriver 的 getTitle 方法獲得。
第二步,在 testng.xml 中添加這個 Web App 的測試用例,然后我們就可以在 Appium Server 已經啟動的情況下執行這個測試用例了。
這個測試用例,首先會自動啟動基於 iOS 10.0 的 iPhone 7 模擬器,然后自動打開 Safari 瀏覽器並訪問 Appium 的官方網站。執行完成后的界面如下圖 13 所示。
圖 13 測試用例執行完成的界面
進行到這里,我們基於 Appium 開發的第一個 Web App 的自動化測試用例,也就開發完成了。
經過前面 Appium 環境搭建,以及兩個測試用例的設計,相信你已經對 Appium 有了一個感性的認識了。那么,Appium 的實現原理又是怎樣的呢?理解了 Appium 的使用原理,可以幫助你更好地使用這個工具,設計更加“有的放矢”的測試用例。
Appium 的實現原理
Appium 作為目前主流的移動應用自動化測試框架,具有極強的靈活性,主要體現在以下 5 個方面:
- 測試用例的實現支持多種編程語言,比如 Java、Ruby、Python 等;
- Appium Server 支持多平台,既有基於 Mac 的版本,也有基於 Windows 的版本;
- 支持 Web App、Native App 和 Hybird App 三大類移動應用的測試;
- 既支持 iOS,也支持 Android;
- 既支持真機,也支持模擬器。
實際應用中,你可以根據項目情況靈活組合完成移動應用的自動化測試。比如,用 Java 寫 iOS 上的 Native App 的測試用例,測試用例跑在 Mac 平台的 iPhone 虛擬機上;或者,用 Python 寫 Android 上的 Web App 的測試用例,測試用例通過 Windows 平台跑在 Android 的真機上。
這樣的組合還有很多很多。那你有沒有想過,Appium 為什么可以做到如此強大的靈活性呢?這就要從 Appium 的基本原理講起了。
要真正理解 Appium 的內部原理,你可以把 Appium 分成三大部分,分別是 Appium Client、Appium Server 和設備端。這三部分的關系如圖 14 所示。
圖 14 Appium 內部原理
我們先來看看處於中間位置的 Appium Server。
Appium Server 有 Mac 和 Windows 版本,也就是說 Appium Server 可以運行在 Mac 或者 Windows 電腦上。本質上,Appium Server 是一個 Node.js 應用,接受來自 Appium Client 的請求,解析后通過 WebDriver 協議和設備端上的代理打交道。
- 如果是 iOS,Appium Server 會把操作請求發送給 WebDriverAgent(簡稱 WDA),然后 WDA 再基於 XCUITest 完成 iOS 模擬器或者真機上的自動化操作;
- 如果是 Android,Appium Server 會把操作請求發送給 appium-UIautomator2-server,然后 appium-UIautomator2-server 再基於 UIAutomator V2 完成 Android 模擬器或者真機上的自動化操作。
Appium Client 其實就是測試代碼,使用對應語言的 Client 將基於 JSON Wire 協議的操作指令發給 Appium Server。
整體來說,Appium 的內部原理可以總結為:Appium 屬於 C/S 架構,Appium Client 通過多語言支持的第三方庫向 Appium Server 發起請求,基於 Node.js 的 Appium Server 會接受 Appium Client 發來的請求,接着和 iOS 或者 Android 平台上的代理工具打交道,代理工具在運行過程中不斷接收請求,並根據 WebDriver 協議解析出要執行的操作,最后調用 iOS 或者 Android 平台上的原生測試框架完成測試。
總結
目前網絡上,Appium 工具使用相關的資料都比較零散,為此我以最新版本的 Appium Desktop 1.6.2 和 Appium Server 1.8.1 為例,手把手地帶你搭建了 iOS 環境,以及 Appium 測試環境,並介紹了如何通過 Appium Inspector 來定位頁面元素。
搭建好了測試環境后,分別針對 Native App 和 Web App 這兩類移動應用,基於 Appium 實現了兩個測試用例,這也是我在這個專欄里面,為你實現的第一個移動應用的測試用例。雖然測試需求比較簡單,但是你也可以從中體會到移動應用測試用例設計的思想、方法。
最后,介紹了 Appium 的實現原理:它屬於 C/S 架構,Appium Client 通過第三方庫向 Appium Server 發起請求,Appium Server 接受請求,然后和移動平台上的代理工具打交道,代理工具在運行過程中不斷接收來自 Appium Server 的請求,並解析出要執行的操作,最后調用移動平台原生的測試框架完成測試操作。