你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> Xcode7 UI自動化測試詳解 帶demo UITests

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

編輯:IOS開發基礎

0.jpg

作者:sunljz 授權本站轉載。

UI Tests是什麼?

UI Tests是一個自動測試UI與交互的Testing組件

UI Tests有什麼用?

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

UI Tests的重要性

在實際的開發過程中,隨著項目越做越大,功能越來越多,僅僅靠人工操作的方式來覆蓋所有測試用例是非常困難的,尤其是加入新功能以後,舊的功能也要重新測試一遍,這導致了測試需要花非常多的時間來進行回歸測試,這裡產生了大量重復的工作,而這些重復的工作有些是可以自動完成的,這時候UI Tests就可以幫助解決這個問題了

使用方法

第一步:添加UI Tests

如果是新項目,則創建工程的時候可以直接勾選選項,如下圖

blob.png

如果是已有的項目,可以通過添加target的方式添加一個UI Tests,點擊xcode的菜單,找到target欄

blob.png

在Test選項中選擇Cocoa Touch UI Testing Bundle

blob.png

這時候test組件添加成功,它在項目中的位置如下圖所示

blob.png

第二步:創建測試代碼

手動創建測試代碼

打開測試文件,在testExample()方法中添加測試代碼

blob.png

如果不知道如何寫測試代碼,則可以參考自動生成的代碼樣式

自動生成測試步驟

選擇測試文件後,點擊錄制按鈕

blob.png

這時候開始進行操作,它會記錄你的操作步驟,並生成測試代碼

下圖就是在一些操作後自動生成的測試代碼

blob.png

這時候可以分析測試代碼的語法,以便你自己手動修改或者手寫測試代碼

開始測試

點擊testExample方法旁邊的播放按鈕,它就開始進行自動測試了,這時候你會看到app在自動操作

blob.png

下面介紹一下測試元素的語法

XCUIApplication:

繼承XCUIElement,這個類掌管應用程序的生命周期,裡面包含兩個主要方法

launch():

啟動程序

terminate():

終止程序

XCUIElement: 

繼承NSObject,實現協議XCUIElementAttributes, XCUIElementTypeQueryProvider

可以表示系統的各種UI元素

exist:

可以讓你判斷當前的UI元素是否存在,如果對一個不存在的元素進行操作,會導致測試組件拋出異常並中斷測試

descendantsMatchingType(type:XCUIElementType)->XCUIElementQuery:

取某種類型的元素以及它的子類集合

childrenMatchingType(type:XCUIElementType)->XCUIElementQuery:

取某種類型的元素集合,不包含它的子類

這兩個方法的區別在於,你僅使用系統的UIButton時,用childrenMatchingType就可以了,如果你還希望查詢自己定義的子Button,就要用descendantsMatchingType

另外UI元素還有一些交互方法

tap():

點擊

doubleTap():

雙擊

pressForDuration(duration: NSTimeInterval):

長按一段時間,在你需要進行延時操作時,這個就派上用場了

swipeUp():

這個響應不了pan手勢,暫時沒發現能用在什麼地方,也可能是beta版的bug,先不解釋

typeText(text: String):

用於textField和textView輸入文本時使用,使用前要確保文本框獲得輸入焦點,可以使用tap()函數使其獲得焦點

XCUIElementAttributes協議

裡面包含了UIAccessibility中的部分屬性

如下圖

blob.png

可以方便你查看當前元素的特征,其中identifier屬性可用於直接讀取元素,不過該屬性在UITextField中有bug,暫時不清楚原因

XCUIElementTypeQueryProvider協議

裡面包含了系統中大部分UI控件的類型,可通過讀屬性的方式取得某種類型的UI集合

部分屬性截圖如下

blob.png

創建Demo

首先創建一個登錄頁面

blob.png

點擊login按鈕進行登錄驗證,點擊clear按鈕會清除文本

登錄成功後可以去到個人信息頁面

個人信息頁面如下

blob.png

點擊modify按鈕可以修改個人信息,點擊Message按鈕可以查看個人消息

最後是消息界面

blob.png

登錄頁面的測試

  1. 輸入一個錯誤的賬號

  2. 驗證結果

  3. 關閉警告窗

  4. 清除輸入記錄

  5. 輸入一個正確的賬號

  6. 驗證結果

  7. 進入個人信息頁面

測試代碼如下:

    func testLoginView() {
        let app = XCUIApplication()
        // 由於UITextField的id有問題,所以只能通過label的方式遍歷元素來讀取
        let nameField = self.getFieldWithLbl("nameField")
        if self.canOperateElement(nameField) {
            nameField!.tap()
            nameField!.typeText("xiaoming")
        }
        let psdField = self.getFieldWithLbl("psdField")
        if self.canOperateElement(psdField) {
            psdField!.tap()
            psdField!.typeText("1234321")
        }
        // 通過UIButton的預設id來讀取對應的按鈕
        let loginBtn = app.buttons["Login"]
        if self.canOperateElement(loginBtn) {
            loginBtn.tap()
        }
        // 開始一段延時,由於真實的登錄是聯網請求,所以不能直接獲得結果,demo通過延時的方式來模擬聯網請求
        let window = app.windows.elementAtIndex(0)
        if self.canOperateElement(window) {
            // 延時3秒, 3秒後如果登錄成功,則自動進入信息頁面,如果登錄失敗,則彈出警告窗
            window.pressForDuration(3)
        }
        // alert的id和labe都用不了,估計還是bug,所以只能通過數量判斷
        if app.alerts.count > 0 {
            // 登錄失敗
            app.alerts.collectionViews.buttons["確定"].tap()
            let clear = app.buttons["Clear"]
            if self.canOperateElement(clear) {
                clear.tap()
                if self.canOperateElement(nameField) {
                    nameField!.tap()
                    nameField!.typeText("sun")
                }
                if self.canOperateElement(psdField) {
                    psdField!.tap()
                    psdField!.typeText("111111")
                }
                if self.canOperateElement(loginBtn) {
                    loginBtn.tap()
                }
                if self.canOperateElement(window) {
                    // 延時3秒, 3秒後如果登錄成功,則自動進入信息頁面,如果登錄失敗,則彈出警告窗
                    window.pressForDuration(3)
                }
                self.loginSuccess()
            }
        } else {
            // 登錄成功
            self.loginSuccess()
        }
    }

這裡有幾個需要特別注意的點:

  1. 當你的元素不存在時,它仍然可能返回一個元素對象,但這時候不能對其進行操作

  2. 當你要點擊的元素被鍵盤或者UIAlertView遮擋時,執行tap方法會拋異常

詳細實現可參照demo:

https://github.com/sunljz/demo/tree/master/iOS9/UITestDemo

個人信息頁測試

  1. 修改性別

  2. 修改年齡

  3. 修改心情

  4. 保存修改

測試代碼如下:

    func testInfo() {
        let app = XCUIApplication()
        let window = app.windows.elementAtIndex(0)
        if self.canOperateElement(window) {
            // 延時2秒, 加載數據需要時間
            window.pressForDuration(2)
        }
        let modifyBtn = app.buttons["modify"];
        modifyBtn.tap()
        let sexSwitch = app.switches["sex"]
        sexSwitch.tap()
        let incrementButton = app.buttons["Increment"]
        incrementButton.tap()
        incrementButton.tap()
        incrementButton.tap()
        app.buttons["Decrement"].tap()
        let textView = app.textViews["feeling"]
        textView.tap()
        app.keys["Delete"].tap()
        app.keys["Delete"].tap()
        textView.typeText(" abc ")
        // 點擊空白區域
        let clearBtn = app.buttons["clearBtn"]
        clearBtn.tap()
        // 保存數據
        modifyBtn.tap()
        window.pressForDuration(2)
        let messageBtn = app.buttons["message"]
        messageBtn.tap();
        // 延時1秒, push view需要時間
        window.pressForDuration(1)
        self.testMessage()
    }

這裡需要特別注意以下兩點:

textview獲取焦點時無法選擇焦點的位置

tap事件的觸發位置是view的中心,所以當view的中心被遮擋時,要考慮使用其他view來代替

個人消息界面測試

單元格的點擊

測試代碼如下:

    func testMessage() {
        let app = XCUIApplication()
        let window = app.windows.elementAtIndex(0)
        if self.canOperateElement(window) {
            // 延時2秒, 加載數據需要時間
            window.pressForDuration(2)
        }
        let table = app.tables
        table.childrenMatchingType(.Cell).elementAtIndex(8).tap()
        table.childrenMatchingType(.Cell).elementAtIndex(1).tap()
    }

這裡需要注意一點:

  1. 暫時無法獲取到tableView的元素指針

總結

總的來說,UI Tests只能用於一些基礎功能的測試,驗證app的功能是否可以正常使用,是否存在崩潰問題。但它也有很多不足之處,編寫測試用例的過程非常繁瑣,自動生成的代碼幾乎無法運行,功能單一,很多用例無法覆蓋,而且bug很多,大大地限制了UI Tests在實際開發中的應用。希望正式版出來的時候能夠修復這些問題,並開放更多的功能。

demo地址:

https://github.com/sunljz/demo/tree/master/iOS9/UITestDemo

歡迎各位提出改進建議,感謝!


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