你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS 9 學習系列:UI Testing

iOS 9 學習系列:UI Testing

編輯:IOS開發基礎

本文由BenBeng翻譯自shinobicontrols iOS9 Day-by-Day :: Day 2 :: UI Testing

在任何軟件的開發中,自動化UI測試都是很重要的。它能快速發現你應用中的問題,在發布之前進行一次成功的配套測試能減少許多問題。在iOS平台目前是通過UIAutomation來完成自動化測試,它的用例是用JavaScript寫的。這需要打開Instruments,在其中編寫和運行腳本。這個流程實在是慢得出奇而且要花很長時間來適應。

UI Testing


在Xcode 7 中,Apple引入了一種新的方式來在你的應用中進行UI測試。UI testing允許你找到UI元素並與之交互,還能檢查屬性和狀態。UI testing已經完全集成進Xcode 7 的測試報告了,可以和單元測試一起執行。在Xcode 5 中XCTest就已經集成到Xcode 的測試框架了,而在Xcode 7 中,XCTest已經擁有進行UI測試的能力了。這樣你就能在檢查UI狀態的時候執行斷言了。

Accessibility

為了讓UI Testing能夠工作,框架需要能夠訪問UI中的各個元素,這樣才能執行它們的動作。你可以定義測試要在哪個特定的點進行點擊和輕掃,但是這在不同屏幕大小的設備上就不那麼好使了,又或者你換算出UI中元素在不同設備上的位置。

這時候accessibility就派上用場了。Accessibility是Apple很早之前構建的一個框架,它能幫助一些行動不便的用戶來更好地使用你的應用。它為你的UI提供了豐富的語義數據,這能讓不同的Accessibility功能給行動不便的用戶展現你的應用。有很多功能都是現成的,直接就能在你的應用中使用,但是你可以(也應該)使用Accessibility的API來改進Accessibility關於UI的數據。在很多場景下這都是必需的,比如對一些自定義的控件,Accessibility就不清楚你的API要做什麼。

UI Testing可以通過你的應用提供的Accessibility功能來與你的應用連接,這樣就解決了設備大小不一的問題。如果你重新調整了UI中的某些元素,你也不用重寫整套測試。實現Accessibility不僅是為了使用UI Testing,也能幫助行動不便的用戶更好地使用你的應用。

UI Recording

當設置好可以訪問的UI之後,你可能就想創建一些UI測試了。編寫UI測試耗時又無聊,如果你的UI比較復雜,那這還有些難度。多虧在Xcode 7中,Apple引入了UI Recording,它能讓你創建新的測試,並擴展原有的測試。當UI Recording打開之後,當你在真機或模擬器上與應用交互時,代碼會自動生成。現在我們已經大概了解了UI Testing是怎麼回事,是時候開始使用它了。

創建 UI 測試


我們會使用新的UI測試工具構建一個demo來展示UI Testing是怎麼工作的。如果你想一起做並看到結果,這有最終完成的demo(Swift?或者Objective-C)。

Setup

當你在Xcode 7中創建新工程時,可以選擇是否要包含UI測試。這會為你設置一個占位的UI Test target,並且配置好了所需的內容。

QQ截圖20150821141934.jpg

demo中的項目設置很簡單,但是足夠我們展示在Xcode 7中UI Testing是如何工作的了。

appLayout.png

menu view controller 包含一個switch和一個button,button連接到detail view controller。當switch“關閉”時,button應該不可點擊,跳轉也就不可能發生。detail view controller包含一個button,點擊button會增加label中的值。

使用 UI Recording

當設置好UI並且可用時,我們就可以編寫一些UI測試來確保代碼的改動不會影響功能。

XCTest UI Testing API

在我們開始錄制動作之前,必須要決定需要斷言什麼內容。我們可以使用XCTest框架來對UI中的某些內容進行斷言,現在框架中已經包含下面三個新API。

  • XCUIApplication。這是你正在測試的應用的代理。它能讓你啟動應用,這樣你就能執行測試了。它每次都會新起一個進程,這會多花一些時間,但是能保證測試應用時的狀態是干淨的,這樣你需要處理的變量就少了些。

  • XCUIElement。這是你正在測試的應用中UI元素的代理。每個元素都有類型和標識符,結合二者就能找到應用中的UI元素。所有的元素都會嵌套在代表你的應用的樹中。

  • XCUIElementQuery。 當你想要找到某個元素時,就會用到 element query。每個 XCUIElement 裡都包含一個query。這些query搜索 XCUIElement 樹, 必須要找到一個匹配的。否則當你視圖訪問該元素時,測試就會失敗。 例外是exists 屬性,你可以使用這個屬性來檢查一個元素是否展示在樹中。 這對於斷言很有用。 更一般地你可以使用 XCUIElementQuery 來找到對accessibility可見的元素。Query會返回結果的集合。

現在我們已經了解了API,可以開始編寫一些測試了。

Test 1– 確保當switch關閉時不會發生跳轉

首先我們必須要定義一個方法來寫測試。

func testTapViewDetailWhenSwitchIsOffDoesNothing(){

}

當定義好方法之後,我們把光標移到方法的括號裡,然後點擊Xcode 窗口下方的錄制按鈕。

prerecording.png

應用會馬上啟動。點擊關閉switch,然後點擊“View Detail” 按鈕。在testTapViewDetailWhenSwitchIsOffDoesNothing??方法裡應該會出現下面的內容。

let app = XCUIApplication()
 app.switches["View Detail Enabled Switch"].tap()
 app.buttons["View Detail"].tap()?

現在再點擊錄制按鈕,錄制應該就會停止了。我們可以看到應用沒有顯示detail view controller,但是目前測試沒有辦法知道。我們必須加一個斷言來判斷沒有發生跳轉。我們可以檢測導航欄的title。這可能不適合所有情況,但對我們這個例子來說足夠了。

XCTAssertEqual(app.navigationBars.element.identifier, "Menu")

在添加完這行代碼之後再次執行測試,應該是能通過的。試著將“Menu”字符串改成“Detail”,應該就失敗了。下面就是這個測試的完整代碼了,其中添加了一些注釋來解釋每一步的操作。

func testTapViewDetailWhenSwitchIsOffDoesNothing() {
    let app = XCUIApplication()
 
    // Change the switch to off.
    app.switches["View Detail Enabled Switch"].tap()
 
    // Tap the view detail button.
    app.buttons["View Detail"].tap()
 
    // Verify that nothing has happened and we are still at the menu screen.
    XCTAssertEqual(app.navigationBars.element.identifier, "Menu")
}?

Test 2– 確保當switch打開時發生跳轉

第二個測試和第一個類似,所以就不詳細講了。唯一的區別是,當switch打開時,應用應該加載detail頁面,XCTAssertEqual會檢查這個。

func testTapViewDetailWhenSwitchIsOnNavigatesToDetailViewController() {
    let app = XCUIApplication()
 
    // Tap the view detail button.
    app.buttons["View Detail"].tap()
 
    // Verify that navigation occurred and we are at the detail screen.
    XCTAssertEqual(app.navigationBars.element.identifier, "Detail")
}

Test 3– 確保“Increment Value”按鈕會增加label中的值

在這個測試中,我們要檢查當用戶點擊“Increment Value”按鈕,label中的值會增加1。測試中的前兩行代碼和之前的類似,所以我們可以直接從之前的測試中復制粘貼。

 let app = XCUIApplication()
 
    // Tap the view detail button to open the detail page.
    app.buttons["View Detail"].tap()

下一步我們需要能訪問這個button。我們之後要點擊幾次button,所以我們把它作為一個變量保存下來。與其我們手動輸入代碼找到這個button,而且還需要調試,不如直接使用錄制功能,點擊“Increment Value”按鈕即可。這樣就得到了下面的代碼。

app.buttons["Increment?Value"].tap()

現在我們可以停止錄制,把代碼改成下面這樣的:

let incrementButton = app.buttons["Increment Value"]

這樣我們就不用手動輸入代碼來找這個button了。我們使用同樣的方法來找到顯示值的label。

let valueLabel = app.staticTexts["Number Value Label"]

現在我們已經有UI元素,就可以和它們交互了。在這個測試中我們會檢查點擊button十次之後,label的值是否也相應地更新了。我們可以錄制十次點擊,但是我們之前已經保存這些元素了,所以可以在循環中完成。

for index in 0...10 {
    // Tap the increment value button.
    incrementButton.tap()
 
    // Ensure that the value has increased by 1.
    XCTAssertEqual(valueLabel.value as! String, "\(index+1)")
}

這三個測試根本算不上全面,但它們應該給你開了一個好頭,你可以在這之上很輕松地擴展。你可以自己寫一個測試來檢查當button可點擊時,你能跳轉,如果關閉switch,又是否能跳轉。

錄制出錯怎麼辦?

某些時候,在錄制時,當你點擊了一個元素,你可能會注意到生成的代碼看上去不太對。這通常是因為你正在交互的元素對Accessibility不可見。你可以使用Xcode的Accessibility Inspector來檢查是不是這種情況。

accessibilityInspector.png

當打開Accessibility Inspector之後 ,如果你按下CMD+F7,並把鼠標懸停在模擬器中的元素上,就能看到鼠標指針下面元素的詳細信息。這應該能幫助你解決為什麼Accessibility找不到你的元素。

當你解決了問題之後,打開interface builder,在 identity inspector你可以找到Accessibility面板。在這你能打開Accessibility,設置hints,、labels 、identifiers和 traits。這些都是很有用的工具來讓Accessibility訪問你的界面。

accessibilityPanel.png

測試失敗怎麼辦?

如果一個測試失敗了,而你不是很清楚為什麼,有一些方法能幫助你解決問題。首先你可以在Xcode的Report Navigator中找到測試報告。

QQ截圖20150821143125.jpg

當打開這個界面,鼠標懸停在測試中的某一步,你會在測試事件的右邊看到一個小眼睛圖標。點擊圖標,會彈出你的應用在特定步驟的截圖。這能讓你可視化查看UI的狀態,找到到底是哪裡出了問題。?

和單元測試一樣,在UI測試中你也可以添加斷點,這樣你就能調試並找到問題。你可以輸出view的層級,檢測accessibility屬性來查看為什麼測試會失敗。

為什麼你應該使用 UI Testing?


自動化UI測試是提升應用質量的一種很好的方式。我們已經看到了在Xcode中設置、執行UI Testing是多簡單,為你的應用添加Accessibility功能不僅能幫助測試你的應用,而且也能幫助行動不便的用戶更好地使用你的應用。

Xcode中的UI Testing的最好的新功能之一,是能在持續集成服務器中執行測試。Xcode bots提供對此的支持,而且command line支持當UI測試失敗時會立即發出通知。

更多


關於Xcode中新的UI Testing的更多內容,我建議你觀看WWDC session 406,?UI Testing in Xcode。還推薦閱讀?Testing in Xcode Documentation和?Accessibility for Developers Documentation。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved