1. 程式人生 > >IOS 自動化 2-UI Automation-功能測試

IOS 自動化 2-UI Automation-功能測試

1. 常用操作

UI Automation提供了非常多的介面來模擬UI操作,如點選、雙擊、雙指縮放、拖曳等。

單擊。根據輸入的絕對座標點選螢幕。

UIATarget.localTarget().tap({x:100, y:200});

雙擊。根據輸入的絕對座標雙擊螢幕。

UIATarget.localTarget().doubleTap({x:100, y:200});

拉伸。模擬雙指拉伸操作,第一個座標點是起點,第二個座標點是終點,最後一個引數是持續時間,單位為秒。

UIATarget.localTarget().pinchOpenFromToForDuration({x:20, y:200}, {x:300, y:200}, 2);

收縮。模擬雙指收縮操作,第一個座標點是起點,第二個座標點是終點,最後一個引數是持續時間,單位為秒。

UIATarget.localTarget().pinchCloseFromToForDuration({x:20, y:200}, {x:300, y:200}, 2);

拖曳。模擬單指拖曳操作,第一個座標點是起點,第二個座標點是終點,最後一個引數是持續時間,單位為秒。

UIATarget.localTarget().dragFromToForDuration({x:160, y:200}, {x:160, y:400}, 1);

快速滑動。模擬單指快速滑動操作,第一個座標點是起點,第二個座標點是終點,與拖曳不同的是它沒有時間引數,因為這個操作的速度很快。

UIATarget.localTarget().flickFromTo({x:160, y:200}, {x:160, y:400});

除了根據絕對座標進行操作,我們也可以先取得控制元件,然後進行相應的操作。當然,前提是這個控制元件是存在、有效且可見的。根據控制元件模擬操作要特別小心,因為有時候控制元件會被其他控制元件擋住,控制元件還沒被加載出來,或者突然出現了彈框導致無法操作控制元件。

var addButton = UIATarget.localTarget().frontMostApp().navigationBar().buttons()["Add"];

if(addButton.isValid() && addButton.isVisible()){

    addButton.tap();

}

如果你還不熟悉UI Automation的介面,那麼錄製功能將給你帶來極大的便利,它會記錄下你每次操作的步驟,生成相應的程式碼。使用方法見UI Automation教程

2. 輸出測試資訊

我們希望編寫的測試指令碼能包含儘可能多的資訊,以便於發現和分析可能出現的錯誤,而記錄資訊最簡單有效的方式就是編寫Case。下面看一個Case。

var testName = "Module 001 Test";

UIALogger.logStart(testName);

//一些測試程式碼

UIALogger.logPass(testName);

UIALogger是一個用於記錄測試資訊的工具類,我們呼叫它的logStart函式開始一項測試,併為測試項命名。因此,上面這個Case的名稱就是"Module 001 Test"。在執行一段測試程式碼後,我們用logPass或logFail結束一項測試,記錄測試結果(成功或失敗)。

我們還可以用logMessage輸出一些資訊,類似於Java或C裡的print。下面的Case就使用了logMessage,它用起來更自由、方便;並用captureScreenWithName截圖,記錄當時的狀態。除此之外,UIALogger工具類還提供了更多的函式如logError, logWarning等,具體用法參見UIALogger

var testName = "Module 001 Test";

UIALogger.logStart(testName);

//一些測試程式碼

UIALogger.logMessage("Starting Module 001 branch 2, validating input.");

//截一張圖,以給定的引數命名

UIATarget.localTarget().captureScreenWithName("SS001-2_AddedIngredient");

//更多測試程式碼

UIALogger.logPass(testName);

3. 處理彈框

UI Automation提供了一個函式介面onAlert來處理彈框,當彈框出現時,將呼叫這個函式。接下來,我們編寫一個非常簡單的彈框處理函式。

UIATarget.onAlert = function onAlert(alert) {

    var title = alert.name();

    UIALogger.logWarning("Alert with title '" + title + "' encountered.");

    // 返回false,使用預設處理方式

    return false;

}

這個函式使用logWarning記錄了彈框的名稱,最後返回false,這將意味著點選預設按鈕來關閉彈框。例如,當收到一條簡訊時,這個函式執行的操作是點選“關閉”按鈕,從而關閉彈框。

如果彈框是app內部產生的,並且我們知道它的確切的名字,那麼我們可以執行一些預期的操作,而不僅僅是關閉彈框。下面的程式碼為一個特定的彈框執行了點選“Continue”按鈕的操作,並返回true,當然前提是我們確定“Continue”按鈕是存在的。

UIATarget.onAlert = function onAlert(alert) {

    var title = alert.name();

    UIALogger.logWarning("Alert with title '" + title + "' encountered.");

    if (title == "The Alert We Expected") {

        alert.buttons()["Continue"].tap();

        return true;  //彈框已處理

    }

    //若返回false,則使用預設處理方式

    return false;

}

4. 指令碼示例

下面以“開源中國”app為例,編寫一個登陸指令碼。點選這裡下載測試應用和指令碼。

var target = UIATarget.localTarget();  //UIATarget是最上層的類,表示真實裝置或模擬器    

try{

    target.delay(3); //等待3秒,跳過開場動畫

    UIALogger.logStart("test 1"); //第1個Case

    UIALogger.logMessage("開始第一個測試");

    var leftButton = target.frontMostApp().navigationBar().leftButton();  //取得導航欄的左側按鈕

    leftButton.tap(); //點選

    var techCell = target.frontMostApp().mainWindow().tableViews()[0].cells()["技術問答"];  //取得第一個cell

    if (techCell.isValid() && techCell.isVisible()) {

        UIALogger.logPass("find 技術問答");

    } else {

        UIALogger.logFail("cannot find 技術問答");

    }

    UIALogger.logStart("test 2"); //第2個Case

    UIALogger.logMessage("開始第二個測試"); 

    target.frontMostApp().mainWindow().buttons()[0].tap();

    target.delay(1); //等待動畫結束

    target.frontMostApp().tabBar().buttons()["我"].tap();

    target.delay(1); //等待動畫結束

    target.frontMostApp().mainWindow().tableViews()[1].cells()["訊息"].tap();

    target.delay(1); //等待動畫結束

    var loginButton = target.frontMostApp().mainWindow().buttons()["登入"];

    if(loginButton.isValid() && loginButton.isVisible()){ //如果登陸按鈕有效且可見,則表示使用者未登入,接下來嘗試登陸

        var textField = target.frontMostApp().mainWindow().textFields()[0];

        var secureTextField = target.frontMostApp().mainWindow().secureTextFields()[0];

        textField.tap();

        textField.setValue("username"); //輸入使用者名稱

        target.delay(0.5);

        secureTextField.tap();

        secureTextField.setValue("password"); //輸入密碼

        target.delay(0.5);

        loginButton.tap();

        target.delay(3);

        if(loginButton.isValid() && loginButton.isVisible()){    

            UIALogger.logFail("登陸失敗");

        }else{

            UIALogger.logPass("登陸成功");

        }

    }else{

        UIALogger.logPass("使用者已經登陸");

    }

}catch(err){

    UIALogger.logError(err.toString());

}

5. 學習資料

如果希望學習更多有關JavaScript指令碼編寫和UI Automation框架的內容,請參考下面的資料。