復雜業務場景下如何進行iOS端自動化測試
之前寫過一篇文章,提到了一些分布式自動化測試和容器化技術結合的架構設想。但是目前來說,分布式運行并不是難點,亟需解決的問題是針對特殊平臺和復雜場景下的測試,例如復雜業務場景下iOS平臺的自動化測試。
移動應用特點是簡單易用和UI簡潔,以便用戶在移動端完成一件事的路徑盡可能短。所以一般情況下,我們遇到的iOS APP場景相對于Web應用要簡單一些。所以一般情況下iOS自動化測試并不會遇見復雜場景,測試反饋時間短,效率相對較高。對運行環境來說,只需要相應版本macOS系統以及Xcode環境即可。
但是,對于大型企業的移動應用,例如電商平臺、共享出行平臺等,牽扯到的主要幾個問題:
1. 大規模的測試用例導致測試反饋時間太長
說到這個問題,就要說到現在主流的移動端自動化測試框架Appium和Calabash。我所經歷過的大部分項目,無外乎使用其一。
但在Xcode 7之后,iOS Simulator變得越來越慢(做iOS的同學們應該都有體會),更不幸的是,在iOS 10、Xcode 8之后,Apple棄用了UIAutomation,導致大量高效、常用的API無法使用。
并且迄今為止,Appium沒有針對iOS 10平臺發布一個正式版本的lib和APP,這就導致一些用戶無法使用inspector定位元素(使用ARC的用戶除外),雖然官方建議不要使XPath進行元素定位,但有的時候我們不得不這么做。***殺器是iOS自動化受到Apple的單例限制(一臺物理主機同一時間有且僅有一個Instrument)。
這些種種最終導致了iOS自動化測試時間太長,更不用談及多種iOS設備的兼容性問題了,自動化實現過程成本過高,令大部分組織和團隊食之無味、棄之可惜。
2. 復雜場景無法在一臺機器上進行測試
對于復雜場景的應用來說,我們很難通過現有框架同時在一臺物理機上控制多個不同的模擬器,也無法隨意的切換到系統級控件去查看APP觸發的通知等等。你可以通過一些合法途徑使用虛擬化做iOS端的并發測試(切記合法途徑)。
但這樣還是逃不掉物理機龐大的開銷以及虛擬機的性能損耗問題,拋開這個問題不講,單從復雜場景來說,例如出行平臺,你需要一臺機器作為乘客發布訂單,還需要多個擁有不同地址定位的車主來測試訂單推送優先級等。對于這種復雜場景來說Appium控制起來就很難了。
3. 測試場景需要切換不同APP
如今很多的APP功能不單單是在應用本身,可能還需要跟系統應用以及其他應用進行交互,例如用戶在被測APP中執行某個操作之后,需要檢查notification,或者在測試的過程中需要切換無網絡環境,從而測試APP的不同行為。
想到這些復雜場景和各種坑之后,估計打算做iOS測試的同學心里開始打退堂鼓了。下面我們來一步步逐一解決這些問題:
問題一:解決Instrument單例的限制
對于這個問題困擾了很久,那業界領先的互聯網公司又是怎么做的呢?有一次看到Uber的Showcase,在一臺機器上啟動了5、6臺模擬器,用不同類型的賬號登錄(乘客、車主)每個模擬器做不同的行為。由于是在物理機上的對iOS模擬器的操作,速度和性能都得到了很好的保證。他們是怎么解決Instrument的限制呢?
我們可以通過使用Apple私有API,同時操作不同型號的模擬器,對多個不同的Simulator進行批量化操作,例如啟動、重置、安裝、運行等操作:
問題二:解決復雜場景下控制不同iOS模擬器的不同行為
xcodebuild命令使我們可以把WebDriverAgent運行在我們想要的設備上,但如果使用Apple的命令,還是只能在單個設備上安裝運行,之前運行的多臺設備都會自動關掉,而只會保留命令中的destination,默認啟動8100端口去檢測這臺設備:
如果這樣的話,那我們之前做的所有工作不就沒有任何意義了嗎?別急,我們已然可以通過Apple提供的資源,對不同的設備啟動不同的進程端口進行監聽。
這時我們可以通過curl命令launch我們需要的進行測試的APP,可以輕而易舉的拿到當前運行APP的session:
- curl -X POST '-H "Content-Type: application/json"' -d "{\"desiredCapabilities\":{\"bundleId\":\"com.apple.Preferences\"}}" http://localhost:8101/session
- response:{
- "value" : {
- "sessionId" : "94A6580F-1F0F-4411-AC64-3E2525BBA5E1",
- "capabilities" : {
- "device" : "iphone",
- "browserName" : "Settings",
- "sdkVersion" : "10.1",
- "CFBundleIdentifier" : "com.apple.Preferences"
- }
- },
- "sessionId" : "94A6580F-1F0F-4411-AC64-3E2525BBA5E1",
- "status" : 0}
同時,對于不同的設備,我們可以通過HTTP server啟動inspector來幫助我們進行APP中的元素定位,即使是系統應用:
問題三:解決不同測試場景需要APP的切換
有了第二個問題的解決方案,只要執行相似的curl命令,就可以拿到不同的APP以及不同的sessionId。
是時候放棄Appium了?
通過Uber的Octopus框架以及Appium正在使用的WebDriverAgent, 不難發現此方案的推廣速度以及樂觀的前景。我們可以使用不同curl命令對不同的Simulator以及APP進行query、tap、typing以及touch id等操作,這與Appium提供的那些我們最常使用的API的等價的,并且由于不需要先去調Appium API 而直接去通過WebDriverAgent與元素進行交互,使得測試執行速度上有不同程度的提高,又由于自身強大的控制力以及靈活性,使其可以輕松進行并發操作和復雜業務場景支持,我們只需要把不同的curl命令進行封裝,結合各自APP的業務場景便可以輕松完成。
帶來的成本?
可以說大部分團隊沒有引入移動端自動化的原因,最主要的無外乎編寫成本高,UI變化快。個人認為這個方案帶來的成本比其帶來的價值要大得多。不再需要QA再去學習新的語言來編寫腳本,所有與APP元素的交互都可通過HTTP請求來完成,元素信息通過易讀的JSON來呈現。我們可以通過任何語言和框架用編寫后端自動化測試的方式完成iOS的自動化測試。
下面通過測試ThoughtWorks的StartKit做一個簡單的登錄頁面的測試Demo(請在原文里點擊鏈接),并且我們已經在超過三個項目中使用過該測試方案。
總結
由于項目因素,我們實踐的場景會相對受限,長時間如此可能會影響我們解決問題的思路,我們應該不時的跳出自己工作之外去思考,把簡單的事情做的復雜,這樣才可以在碰到復雜問題的時候,做的簡單。
【本文是51CTO專欄作者“ThoughtWorks”的原創稿件,微信公眾號:思特沃克,轉載請聯系原作者】