UITests操作指南

灰s發表於2017-12-22

UI Tests有什麼用?

它可以通過編寫程式碼、或者是記錄開發者的操作過程並程式碼化,來實現自動點選某個按鈕、檢視,或者自動輸入文字等功能。

1. 新增UI Tests

  • 如果是新專案,則建立工程的時候可以直接勾選選項,如下圖

image.png

  • 如果是已有的專案,可以通過新增target的方式新增一個UI Tests,點選xcode的選單,找到target欄並點選,在Test選項中選擇iOS UI Testing Bundle

image.png

新增成功

預設的UITests方法都是以test開頭的。這裡的testExample是系統自動生成的方法。

image.png

2. 新增測試程式碼

有兩種方式

  • 手動新增

新手不推薦自己寫,很麻煩,坑也很多。我也是用的自動新增,然後再自己調整。

  • 自動新增

image.png
這裡有個操作技巧。就是開始錄製了以後(也就是app啟動了以後),可以再次點選這個按鈕來暫停,某些不需要記錄的操作完成以後,可以再次點選啟動。這樣在同一個邏輯需要多次調整的時候,就可以避免一些重複程式碼了。

3. 再次執行寫好的Test

image.png

自動新增的程式碼,你再次執行這個測試用例的時候,不一定能正常執行,會有一些bug,需要再次調整。

注意事項:

  • 如果你下一步需要點選的控制元件被某個檢視擋住了,你需要先隱藏遮蓋檢視,再進行點選,否則會報錯。比如在顯示Hud的時候和鍵盤彈出的時候,收鍵盤需用最直觀的方式,類似點選鍵盤上面的returnDone,而不是點選空白區域那種。
  • textField.typeText("") 方法是直接在當前內容的後面進行新增,這裡我是把清空的按鈕在輸入期間顯示了出來,如果需要完全的更改textFieldtext,就先點選清空按鈕。
  • 獲取到的控制元件資料,基本都是陣列的形式,然後根據一個值來篩選,自動生成的一般是根據text或者title來篩選,某些介面可能存在兩個按鈕的title一樣,或者兩個textFieldtext一樣,所以需要通過一個額外的屬性來篩選,也就是accessibilityIdentifier,這個屬性需要手動設定。至於篩選的方法就是類似app.buttons.element(matching: .button, identifier: T_LoginBtn)
  • 部分控制元件獲取不到可能是因為isAccessibilityElement屬性被設定成了NO,不過這個屬性的預設值是YES,我也不太清楚什麼情況下他會變成NO,下面是Apple的註釋。
 Return YES if the receiver should be exposed as an accessibility element. 
 default == NO
 default on UIKit controls == YES 
 Setting the property to YES will cause the receiver to be visible to assistive applications. 
複製程式碼
  • tableView中獲取cell上面的控制元件,系統自動生成的程式碼會獲取cell的集合,然後根據title或者text之類的屬性來篩選類似下面這段程式碼,明顯這不是一個好的方式。這種情況我們可以獲取cell的集合,然後根據index來選擇指定的cell。具體的程式碼可以參考下面購物車的測試程式碼。
tablesQuery.cells.containing(.staticText, identifier:"澳洲直郵Devondale德運奶粉高鈣全脂奶粉成人奶粉1kg ")
複製程式碼
  • 當程式碼重複進行多次點選的時候,比如寫個for迴圈點選50次,你並不需要考慮點選太快會不會出現什麼問題,因為每次點選的中間,系統都會有個等待響應的時間,只有當程式空閒的時候,才會進行點選。不過,具體執行方式可能不是我說的這樣,不過確實有個類似的等待時間。上面的這種說法只是我自己的理解。
  • UITests可以配合斷言來使用,我個人對斷言用的並不是很好,這兩段Demo裡面並沒有用到斷言,如果需要請自行新增。類似下面的程式碼,就是判斷textField是否存在。 XCTAssertEqual(textField.exists, true)

4. 下面是兩個我寫好的測試程式碼

1. 登入的模擬測試,這個要複雜一些,涉及了介面跳轉和一些重複點選。

2. 購物車的模擬測試,這個主要是給大家看看tableView這類集合檢視的操作。

這是我專案的tabbar,兩段測試程式碼最開頭都有app.tabBars.buttons["我的"].tap()這種程式碼,就是tabbar的切換。程式碼的前面會附上購物車和登入介面的設計圖。

image.png

image.png
image.png

    /**
     這裡分三步:
     1. 國家地區為中國時,判斷手機號是否正確
     2. 國家地區不是中國時,判斷手機號是否正確
     3. 正確的賬號密碼,登入功能
     */
    func testLogin() {
        let app = XCUIApplication()
        let window = app.windows.element(boundBy: 0)
        app.tabBars.buttons["我的"].tap()
        window.press(forDuration: 1)
        //---------------------1
        //找到手機號的輸入框
        let textField = app.textFields["請輸入手機號"]
        XCTAssertEqual(textField.exists, true)
        //點選
        textField.tap()
        //修改輸入框的輸入
        textField.typeText("187027813111")
        //獲取清空手機號的按鈕
        let clearTextButton = app.textFields["請輸入手機號"].buttons["Clear text"]
        //收鍵盤
        app.buttons["確定"].tap()
        //找到登入按鈕
        let button = app.buttons.element(matching: .button, identifier: T_LoginBtn)
        //點選登入
        button.tap()
        //暫停2秒
        window.press(forDuration: 2)
        //---------------------2
        //跳到選擇國家介面
        let selectCountry = app.buttons["login arrow"]
        selectCountry.tap()
        let tablesQuery = app.tables
        //選中一個國家並返回
        tablesQuery.staticTexts["愛沙尼亞"].tap()
        //點選登入
        button.tap()
        //暫停2秒
        window.press(forDuration: 2)
        textField.tap()
        //清空賬號資訊
        clearTextButton.tap()
        textField.typeText("18702781315")
        //收鍵盤
        app.buttons["確定"].tap()
        //再次選中國家
        selectCountry.tap()
        tablesQuery.staticTexts["中國"].tap()
        //點選登入
        button.tap()
        //暫停2秒
        window.press(forDuration: 2)
        //---------------------3
        let pwdTextField = app.secureTextFields.element(matching: .secureTextField, identifier: T_PWDLoginKey)
        pwdTextField.tap()
        pwdTextField.typeText("123456")
        //輸入完成點選確認按鈕
        let doneButton = app.buttons["Done"]
        doneButton.tap()
        
        button.tap()
    }
複製程式碼

image.png

    /**
     購物車的測試模型
     */
    func testShopCart() {
        let app = XCUIApplication()
        app.tabBars.buttons["tab shopcart"].tap()
        //獲取tableView的所有cell
        let tablesCells = app.tables.cells
        //遍歷cell
        (0..<tablesCells.count).forEach { (index) in
            let cell = tablesCells.element(boundBy: index)
            cell.buttons["shopCart add"].tap()
            cell.buttons["shopCart add"].tap()
            cell.buttons["shopCart add"].tap()
            cell.buttons["shopCart reduce"].tap()
            cell.buttons["shopCart reduce"].tap()
            cell.buttons["shopcart unselect"].tap()
            cell.buttons["shopcart unselect"].tap()
        }
    }
複製程式碼

參考連結:

Xcode7 UI自動化測試詳解 帶demo UITests

相關文章