當你在閱讀本教程時,可能同時有數百萬、甚至數十億用戶正在瀏覽智能手機上的 App,擁有大量 App 的智能手機已經成為我們生活中不可或缺的一部分。每天有如此多的用戶不斷在使用手機 App,我們必須確保用戶介面 (UI) 運行順暢,不讓用戶感到失望;而編寫良好的自動化測試就可以實現這一點。
特別感謝 Sauce Labs,它們推出的 Appium 可以幫助測試工程師運行自動化 UI 測試,且這些測試都集中在一個平台上。因此,在本教程中,我將向讀者介紹甚麼是 Appium,以及如何使用這工具自動化 iOS App 的 UI 測試 。
甚麼是 Appium?
首先,Appium 到底是什麼?它是一個開源測試自動化工具,本質上是一個 HTTP Web Server(主從式架構),能夠管理多個 WebDriver sessions,並公開 REST API。當與 Selenium WebDriver API 和特定於語言的 Client Libraries 結合使用時,它可以獲得更多功能來編寫從原生到跨平台應用程式的進階測試範例。此外,你亦可以自行選擇語言來編寫測試範例(即 C#、.NET、Java、node、Perl、PHP、Python、Ruby 等)。
Appium 的概念,是對原生 (Native) App 的自動化測試,不需要包含其它 SDK 套件或重新編譯 App。而且,你應該能夠使用偏好的測試方法、框架和工具。Appium 是一個開源項目,通過一系列設計和工具抉擇,鼓勵廣大開發者為社區貢獻。
Appium 最棒的地方是它支持大部分類型的 App,包括原生、Mobile Web 和 Hybrid App。也就是說,你在 iOS 和 Android 上都可以運行測試!
自動化測試如何運作?
這是個好問題!很簡單!以我將在教程展示的範例為例,你使用 Python 編寫測試範例;Selenium 的 WebDriver 將其轉換為原生的 iOS 和 Android 指令。然後,這些指令將發送原生驅動程序到你的模擬器或真實設備上。
Appium 還有其他好處嗎?
Appium 是基於以下的四個理念設計,來滿足手機平台自動化的要求的;
1. 不應該為了自動化測試而以任何形式去重新編譯或修改你的 App;
2. 不應該固定於一門特定的語言或框架中來編寫和運行你的測試;
3. 測試自動化 API 時,不應該重頭編寫一個手機測試框架;
4. 一個手機測試自動化框架應該是開源的,無論是在精神上、實際上、還是名義上!
當然有!App 設定好 UI 元件後,就準備就緒可以運行測試範例。只需要簡單挑選 App,無需重新編譯,standard API 就將處理所有事情!然而,還有一個問題:由於兩個原生平台(iOS 和 Android)具有非常不同的 UI 元素,因此你需要編寫兩套測試範例。
上圖簡單介紹了 Appium、客戶端和 Web script 之間的通信路徑。
先決條件
要學習本教程,你先要具備以下條件:
- Swift 中 iOS 編程的一些基礎知識
- 在 macOS 上安裝 Xcode 9.4.1或更新版本
- 熱衷於學習如何在 iOS 專案上運行 UI 自動化測試
你將在本教程中學到甚麼?
你將學到很多關於 Appium 的知識,包括:
- 如何設定 Appium
- 如何編寫 Web Scripts 測試範例
- 如何設定 Xcode 專案以備進行 UI 測試
- 如何整合 Appium、Script & 客戶端自動化測試範例
安裝 Appium
首先,你需要設置本教程的核心:Appium!Appium 是用 Node.js 編寫的,有兩種方法可以安裝:
- 使用 Appium 自己的 GUI 從此連結進行安裝
- 使用以下指令透過 NPM 安裝:
npm install -g appium
安裝 Appium 後,通過在終端機中運行 appium
來驗證是否已安裝 Appium。
現在已經安裝了 Appium,讓我們處理客戶端。
為 UI 自動化設置範例專案
完成本教程後,你將能夠自動執行上述兩個螢幕的 UI 測試。簡而言之,這些就是測試範例:
- 用戶在 text field 中輸入電郵地址,而電郵地址應該是有效格式。
- 用戶在密碼欄位中輸入密碼,而密碼應該被遮蔽。
- 當用戶點擊 “Login” 按鈕時,用戶應該看到笑臉圖像。
我們將使用 Appium 實作這些測試範例。為了更專注構建測試範例,你可以在此處下載範例項目專案。
對於 UI 測試自動化,一定有些識別 UI 元素的測試工具。讓 Appium 識別正確 UI 元素以進行測試的其中一個方法,就是 Accessibility ID
。請打開 Xcode 專案,並前往 Main.storyboard
。選擇 Email text field,然後查看 Identity inspector,在 Accessibility 欄位下,勾選 enable “Accessibility“。為 Label 命名,像是 Email TextField
,並在 Identifier 欄位填入 emailTextField
,這是一個專屬 ID,讓我們在 Python 測試腳本中標識 UI 元素。
對其它 UI 元件重複上述設置步驟:
- Password 欄位 ── 在 Identifier 欄位填入
passwordTextField
- Login 按鈕 ── 在 Identifier 欄位填入
loginButton
- 笑臉圖像 ── 在 Identifier 欄位填入
smileyImage
很好!客戶端設置完成,準備接收指令!
設定 Web Scripts
在這個範例專案中,我將使用 Python script 為選擇的語言,你可以查看他們的 API 文件來探索其他語言。
接下來,選擇要創建工作區的文件夾,我會把它放在 Documents/workspace/appium-ios-basic/tests
之下。創建一個名為 test_login.py
的文件,請注意 .py
是 python 文件的副檔名。
你可以使用 TextEditor
如 Sublime Text,或 IDE
如 Atom 來編輯 script,我個人偏好使用 Atom,因為用戶介面更好。
在 test_login.py
文件中,輸入下列指令:
import unittest import os from random import randint from appium import webdriver from time import sleep from selenium.webdriver.common.keys import Keys
這些是我們執行測試範例所需的基本功能。
LoginTests 類別
現在讓我們開始編寫 LoginTests 類別吧!由於本教程的目的,只是讓你了解 Appium UI 自動化作業的步驟,所以我將跳過 Python 語法的解釋,你可以自行閱讀。首先,輸入以下程式碼來創建類別:
class LoginTests(unittest.TestCase):
接下來,我們將為測試類別編寫幾個函式,首先使用 unitTest
中的 initialising
函式進行一些設定:
def setUp(self): app = ('/Users/lawrey/Library/Developer/Xcode/DerivedData/AppiumTest-fubxvjmcpxiewkenopxpcerwhudw/Build/Products/Debug-iphonesimulator/AppiumTest.app') self.driver = webdriver.Remote( command_executor='http://127.0.0.1:4723/wd/hub', desired_capabilities={ 'app': app, 'platformName': 'iOS', 'platformVersion': '11.4', 'deviceName': 'iPhone 6s' } )
這裡有幾點需要注意:
- 你需要以本地端電腦上
AppiumTest.app
的絕對路徑 (Absolute Path) 取代app
。 - 根據閱讀本教程的時間,你可能需要調整
platformVersion
和deviceName
的設定。 - 其他設定可以不用更改,但是如果你在另一台服務器上運行 Appium,你可以更改 URL。
接下來,讓我們創建 tearDown
函式:
def tearDown(self): self.driver.quit()
測試範例全部執行完之後,釋放驅動程式的動作非常重要。
測試範例 #1 ── testEmailField
第一個測試範例是用於測試 Email TextField 的 UI 元件。在 test_login.py
文件中,編寫下列測試範例:
def testEmailField(self): emailTF = self.driver.find_element_by_accessibility_id('emailTextField') emailTF.send_keys("[email protected]") emailTF.send_keys(Keys.RETURN) sleep(1) self.assertEqual(emailTF.get_attribute("value"), "[email protected]")
我們一起看看上面的程式碼:
self.driver.find_element_by_accessibility_id
會搜索emailTextField
UI 元件,並將其分配給emailTF
。- 接下來,我們將使用
send_keys
輸入有效的電郵地址。 - 完成後,我們將使用
Keys.RETURN
點擊Return
。 - 然後,調用
sleep
來延遲 1 秒。 - 最後,使用 assert 測試從 text field 取得的值是否與預期值相同。
測試範例 #2 ── testPasswordField
第二個測試範例,是檢查密碼欄位是否可以自動遮蔽輸入值。繼續在 Python script 文件中輸入以下程式碼:
def testPasswordField(self): passwordTF = self.driver.find_element_by_accessibility_id('passwordTextField') passwordTF.send_keys("validPW") passwordTF.send_keys(Keys.RETURN) sleep(1) self.assertNotEqual(passwordTF.get_attribute("value"), "validPW")
程式碼看起來與第一個測試範例非常類似,最主要的差異是這裡我們使用 assertNotEqual,以確保密碼欄位的值已經遮蔽了。
測試範例 #3 ── testLogin
最後,我們將執行 UI Flow 測試,以確保我們在登錄成功後會看到笑臉圖像。在 script 文件中輸入以下程式碼:
def testLogin(self): self.testEmailField() self.testPasswordField() self.driver.find_element_by_accessibility_id('loginButton').click() sleep(1) smiley = self.driver.find_element_by_accessibility_id('smileyImage') self.assertTrue(smiley.get_attribute('wdVisible'))
我們只要依序調用每個測試函式,然後找到 loginButton
,並調用 click()
函式進行點擊。最後,我們測試笑臉圖像是否可見就完成了!
啊!等一下,我們需要調用 main 來為我們執行整個類別內的程式碼!
if __name__ == '__main__': suite = unittest.TestLoader().loadTestsFromTestCase(LoginTests) unittest.TextTestRunner(verbosity=2).run(suite)
我們已完成測試範例的設定,現在來到最令人興奮的部分了,看看運行結果吧!
安裝 Appium Python 客戶端
要安裝 Appium 客戶端,請運行 pip --version
確保你已安裝 Python。在我撰寫本文時,使用的版本是 pip 18.0,python 2.7
。如果你的電腦上沒有安裝 Python,可以使用 homebrew
來安裝:
brew install python
安裝 Python 後,輸入以下命令安裝 Appium Python 客戶端:
pip install Appium-Python-Client
你也可以前往 Appium 下載原始碼並進行安裝。這是一個主要連接器,對於確保 Appium 為客戶端挑選出正確語言十分重要。
安裝 PyTest
這個小型 python 框架是一個功能齊全的進階測試工具,可以幫助我們進行測試!在本教程中,我們可能不需要此框架的全部功能,但它擁有非常好的格式化日誌 (formatted loggings),使我們的測試範例看起來更悅目!
要安裝 PyTest,你可以在終端機中執行以下命令:
pip install -U pytest
安裝 Carthage
Appium 是通過 XCUITest 驅動程式提供主要支援予自動化 iOS App 的,這個驅動程式利用 Apple 的 XCUITest 函式庫促使 App 的自動化。而對 XCUITest 的訪問是由 WebDriverAgent server 操作的。
要啟動 WebDriverAgent,你的 macOS 需要安裝 Carthage。如果尚未安裝該軟件,請運行以下指令進行安裝:
brew install carthage
使用 XcodeBuild 構建 App
要準備好進行測試的 App,請透過 XcodeBuild 使用特定的 SDK 構建它。假設你已更改為 Xcode 專案文件夾,請輸入以下指令以進行構建:
xcodebuild -sdk iphonesimulator11.4
這將編譯專案,並在 build
文件夾下創建 build 檔。你可以找到一個 build/Release-iphonesimulator
目錄,裡面包含了你需要與 Appium server 通信的 .app package。範例路徑如下:
/Users/test/Downloads/appium-ios-basic-master/final/build/Release-iphonesimulator/AppiumTest.app
針對 test_login.py
文件,請確保你已更改對應的 App 路徑。
運行測試範例
現在就是運行測試的時候了!在終端機中執行以下指令:
pytest test_login.py
然後,你的 Appium server 就會執行自動指令!
你應該會看到一個訊息,說明執行測試所花費的時間、以及通過了多少個測試範例!太棒了!
總結
那麼我們完成了哪些事情?
- 我們學到 Appium 如何與 Web Script 和 Client 進行交互。
- 我們學到如何 設定 Appium。
- 我們學到如何 編寫 Python Test Scripts(測試腳本)。
- 我們學到如何在 Xcode 中存取 UI 元件,以便對其進行測試。
- 我們學到如何整合 3 個主要元件,來自動化單個 UI 自動化測試流程。
我們都應該好好表揚一下自己,除了因為你們看完了本教程外,也因為你完成這個漫長的過程還自動測試順利運行!
如果你對本教程有任何疑問,歡迎在下面留下評論告知我們。
你可以在 GitHub 下載範例專案的完整原始碼。
如果你希望我編寫後續教程,教大家使用 Appium 為 iOS 編寫更進階的測試技術,歡迎留言讓我知道。
FB : https://www.facebook.com/yishen.chen.54
Twitter : https://twitter.com/YeEeEsS
原文:UI Test Automation: Speed Up Mobile App UI Testing with Appium