IOS9每天多一點了解2:UI測試
自動化測試用戶界面工具對于開發(fā)軟件來說是非常有用的,他可以快速的幫你定位到問題。一套成功的測試流程,可以為你最終發(fā)布軟件帶來信心。在iOS平臺上,我們使用 Automation 來完成這個工作。這要打開一個單獨的應(yīng)用 Instruments,然后編寫和運行 JavaScript 腳本。整個流程痛苦且漫長。
UI Testing
在Xcode7中,蘋果介紹了一種新的方式來管理你的應(yīng)用界面的測試工作。UI testing 允許你對 UI 元素進(jìn)行查找,交互,驗證屬性和狀態(tài)。在 Xcode7 中,UI testing 伴隨著測試報告,并且和單元測試一起運行。 XCTest 是在 Xcode 5 時融入到測試框架的,在Xcode7 中,新增了對 UI 的測試能力。允許在特定點設(shè)置斷言,查看UI當(dāng)時的狀態(tài)。
Accessibility(輔助功能)
為了 UI Testing 能夠工作,框架需要和你的眾多元素直接建立連接,然后安排好操作。你可以設(shè)定義特別的點,或者在某個 UI 上創(chuàng)建 tweak,然后指定點擊或者滑動操作。但是這在不同尺寸設(shè)備上就失效了。
這時候 accessibility,就能提供幫助了。Accessibility 是蘋果早就發(fā)布的一個框架,提供給有一定身體障礙(例如失明)的人使用,讓他們能夠操作和使用你的應(yīng)用。他把你的 UI 以語義話的方式提供給這些用戶,允許他們進(jìn)行豐富的操作。你可以(也應(yīng)該)讓你的元素具備Accessibility的能力。有很多原因,比如說自定義的控件,不能夠被自動發(fā)現(xiàn)。
UI Testing 有能力通過你的應(yīng)用提供給 Accessibility 的特性,來對不同尺寸的設(shè)備進(jìn)行測試提供解決方案。也保證了你在重新組織了一下你的 UI 之后,不必全部重新寫一套測試。不僅能夠幫助你測試自己的 UI,同時也能夠?qū)δ愕膽?yīng)用,更好的支持有一定身體障礙的人群使用而帶來幫助。
UI 錄制
一旦你設(shè)置好了你的 accessible UI,你將要創(chuàng)建 UI 的測試項。編寫 UI 的測試是非常耗時,無聊的,如果你的 UI 比較復(fù)雜,也是非常困難的。感謝 Xcode7, 蘋果介紹了 UI Recording. 他允許你新建、或者在已有項目中創(chuàng)建測試。當(dāng)你打開時,測試代碼會隨著你在設(shè)備或模擬器上操作自動創(chuàng)建。好了,簡介到此結(jié)束,是時候用一個例子來看一下,如何使用了。
創(chuàng)建 UI 測試?yán)?/strong>
我們將通過UI Testing套件來創(chuàng)建一個實例,展示 UI Testing 是如何工作的。最終的demo 可以在Github下載,你可以跟著我們一起來練習(xí)和查看結(jié)果。
創(chuàng)建
在Xcode7中,當(dāng)你創(chuàng)建新項目時,如果選擇包含 UI Tests,將會為你創(chuàng)建一個新的 target,你可以在彈出框中設(shè)置所有你想要的配置。
本項目非常簡單,但已經(jīng)足夠幫我們演示 UI Testing 在 Xcode 7 中是如何工作的了。
這里有一個 menuViewController,里面包含一個 switch 和一個 button。點擊 button,可以 push 到 detailViewController 頁面。當(dāng) switch 的狀態(tài)為 off 的時候,是禁止 push 的。詳細(xì)頁面有一個按鈕和一個標(biāo)簽,點擊按鈕可以增加標(biāo)簽的值。
使用 UI Recording
一旦UI控件創(chuàng)建好,并且寫好了方法。我們就可以寫測試單元,確保代碼的變化,不會影響方法的效果。
The XCTest UI Testing API
在我們錄制測試的動作之前,我們需要決定斷言放在哪里。為了能夠測試我們的UI,我們可以使用 XCTest Framework,他現(xiàn)在擴充了三個新的 API。
- XCUIApplication 這是你要測試的應(yīng)用的代理,他能夠把你的應(yīng)用啟動起來,并且每次都在一個新進(jìn)程中。這可能會花一點兒時間,但這意味著每次要測試你的應(yīng)用時,他都會把需要處理的工作完成,保持一個干凈的,全新的狀態(tài)。
- XCUIElement 這是你要測試的應(yīng)用的 UI 元素的代理。元素都有類型和唯一標(biāo)識。你可以結(jié)合使用來找到你的元素在哪里,這些元素以樹狀結(jié)構(gòu)組合,構(gòu)成了你的應(yīng)用的表現(xiàn)形式。
- XCUIElementQuery 當(dāng)你要要查找元素時,會用到 XCUIElementQuery, 每一個 XCUIElement 基于一個查詢。這個查詢必須在你的元素樹上找到對應(yīng)的元素,否則就會失敗。異常信息會提示不存在,你可以去檢查一下是否展現(xiàn)在樹上了。XCUIElementQuery 具有通用性,如果你查找一個輔助功能支持的元素,查詢會返回一組結(jié)果。
現(xiàn)在我們準(zhǔn)備好寫測試了,通過這個測試來進(jìn)一步解釋提到的這些API。
Test 1 - 確保switch關(guān)閉時,導(dǎo)航不能生效
首先我們定義一個測試方法。
- func testTapViewDetailWhenSwitchIsOffDoesNothing() {
- }
定義好方法后,我們讓光標(biāo)移到方法中,點擊Xcode窗口底部的錄制按鈕。
現(xiàn)在應(yīng)用啟動起來了,點擊一下 switch, 讓其處于關(guān)閉狀態(tài),然后點擊一下“View Detail”按鈕,下面這些代碼會自動插入到 `testTapViewDetailWhenSwitchIsOffDoesNothing`方法中.
- let app = XCUIApplication()
- app.switches["View Detail Enabled Switch"].tap()
- app.buttons["View Detail"].tap()
現(xiàn)在再點一下錄制按鈕,錄制會停止下來??梢钥吹?,實際上并沒有 push 到 detailViewController 頁面。但這時測試并不知道,我們要加個斷言,判斷一下沒有變化。我們可以比較導(dǎo)航欄的標(biāo)題值,這并不優(yōu)雅,但當(dāng)前演示就夠了。
- XCTAssertEqual(app.navigationBars.element.identifier, "Menu")
添加了這一行斷言后運行,發(fā)現(xiàn)測試還是能夠通過。如果你把導(dǎo)航欄的標(biāo)題改為“Detail”,你會發(fā)現(xiàn)測試通過不了了。下面試最終的測試代碼,加了一些解釋行為的注釋。
#p#
Test 2 - 確保 switch 的狀態(tài)為 on 時,導(dǎo)航可以正常工作
第二個測試前面的非常相似,我們就不細(xì)講了。唯一的區(qū)別是switch是可用狀態(tài),所以應(yīng)用會加載詳細(xì)頁面到屏幕上。XCTAssertEqual 方法來驗證是否正確。
Test 3 - 確保增長按鈕確實增加了標(biāo)簽的值
在這個測試中,我們要驗證點擊了增長按鈕,標(biāo)簽的值是否會加1.前兩行代碼和前面的例子很像,我們復(fù)制過來。
- let app = XCUIApplication()
- // Tap the view detail button to open the detail page.
- app.buttons["View Detail"].tap()
下一步我們要得到button,我們將多點擊幾下。所以我們要把按鈕作為一個變量。我們不必手寫代碼和 debug 他。再次錄制并且點擊一下 increase 的按鈕,這會自動給你添加下面的代碼。
- app.buttons["Increment Value"].tap()
我們停止錄制,把代碼改成下面這樣。
- let incrementButton = app.buttons["Increment Value"]
這種方法,讓我們不必手動編寫代碼,同樣的方式,我們獲的 lable 變量。
- let valueLabel = app.staticTexts["Number Value Label"]
現(xiàn)在我們得到了能夠交互的感興趣的元素。下面這個測試中,我們測試點擊10次 button 按鈕,看標(biāo)簽的值是否隨之增長。我們可以錄制10遍,但既然我們得到了變量,我們可以寫一個循環(huán)來測試它。
這三個測試離一個完整的測試距離甚遠(yuǎn),但給你展示了一個很好的開始,你可以輕松的擴展開來。為什么不寫一個自己的測試練習(xí)一下呢。比如去驗證一下 button 是 enable 的 時候,你可以在switch 關(guān)閉的情況下導(dǎo)航成功呢?
當(dāng)錄制發(fā)生錯誤時
有時候你發(fā)現(xiàn)你在錄制的時候,點擊了一個元素,但是產(chǎn)生的代碼看起來不正確。通常這是由于你的元素對于 Accessibility 是不可用的。為了確定是否是這個原因,你可以打開Xcode的Accessibility Inspector。
一旦打開Accessibility Inspector,如果你按下CMD+F7,鼠標(biāo)懸浮在元素上時,你可以在熱點下面,看到完整的元素的信息。這能夠在你找不到元素時給你提供一些線索。
一旦你找到問題所在,你可以打開 Interface Builder.在屬性攔里找到 Accessibility 欄。他允許你設(shè)置元素的 accessibility。這是個強大的工具,設(shè)置你的圖形接口的 accessibility 屬性。
當(dāng)測試失敗時
當(dāng)測試失敗時,如果你不確定為什么?有很多辦法能夠幫你修復(fù)錯誤。首先,你可以去測試報告里看一看。
當(dāng)你打開這個視圖,將鼠標(biāo)懸停在某一步上時,你會發(fā)現(xiàn)在方法的右面有一個小的眼睛圖標(biāo)。點擊一下這個眼睛圖標(biāo),會給你一個當(dāng)時的截圖,你能夠清晰的看到當(dāng)時你的UI的狀態(tài)以便發(fā)現(xiàn)錯誤。
和單元測試一樣,你可以設(shè)置斷點,允許你更方便的發(fā)現(xiàn)問題。你可以輸出UI的層次結(jié)構(gòu),元素的屬性等,然后找到原因。
為什么要進(jìn)行UI測試
UI自動化測試是一個很好的辦法,為你在修改應(yīng)用時,提高信心,并提供質(zhì)量保證,。我們已經(jīng)看到了,在 Xcode 中添加 UI 測試和運行是多么簡單。他不僅幫助你發(fā)現(xiàn)問題,并且能夠?qū)τ胁糠止δ苷系K的人使用你的應(yīng)用提供幫助。
Xcode 的一個特別好的特性是,可以從 continuous integration server 來測試你的應(yīng)用。這個可以利用 Xcode 的機器人來進(jìn)行測試,并且 from the command line 意味著,如果一個測試失敗,你會第一時間被通知到。