UI AutomationでiPhoneテストが全自動に!

UI Automationという機能を用いることで、iPhoneの動作テストは
ほぼ全自動で行うことができます。過去にいくつか記事があがっているのですが、
認知度低そうなのでここでも書いてみます。


テキスト入力とタップによる画面遷移の自動化
では、実際に自動化してみます。
テキスト入力してボタン押す機能の自動化です。
以下のような画面とコードのテストです。


自動化テストは、メモリリークとかのテスト行うのと同じInstrumentsから実行できます。
Runボタン押しっぱなしでProfileに切り替えることが出来ます。ここからInstrumentsを起動します。

起動したらAutomationを選びます。


自動テストの画面はこんなのです。
Recordで開始して、Scriptのところにjavascriptで描いたテストコードを
入力して、StartScriptを押します。

使ったコードは以下のものです。

var target = UIATarget.localTarget();
var app = target.frontMostApp();
var main = app.mainWindow();
UIALogger.logDebug("textLen:"+main.textFields().length);

var i;
for(i=0;i<2;++i){
    //i番目のテキストフィールドを対象として選ぶ
    var text = main.textFields()[i];
    //テキストフィールドをタップ
  text.tap();
  //選択されているテキストフィールドに文字を入れる
    text.setValue('view1 input'+i);
        
}

//2秒待つ
target.delay(2.0);
//ボタンを押して画面を切り替える
main.buttons()[0].tap();
target.delay(1.0);

for(i=0;i<2;++i){
  //i番目のテキストフィールドを対象として選ぶ
    var text = main.textFields()[i];
   //テキストフィールドをタップ
    text.tap();
  //選択されているテキストフィールドに文字を入れる
    text.setValue('view2 input'+i);
}

target.delay(2.0);
//ボタンを押して画面を切り替える
main.buttons()[0].tap();


自動テストの動画
動作結果は以下のリンクに貼っておきました。
iPhoneの自動テストの動画

テキストの入力自動化も指定した通り行えますし、
ボタンを押して画面を遷移してくれるので、ほとんどのUI操作は自動テストできるのでは
ないでしょうか。

参考になる文献
http://developer.apple.com/jp/devcenter/ios/library/documentation/InstrumentsUserGuide.pdf
Instrumentsのユーザーガイドです。109ページからAutomationの説明があります。

リファレンスです。公式のものなのでチェックしときましょう。
http://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/UIAutomationRef.pdf

対応関係表です。各コンポーネントにアクセスするためにはUIAutomation用のキーワードがいるので
個の対応関係表はすごく便利です。
UIKitのクラス名と、UI Automationでのクラス名の対応 - Over&Out その後

対応関係の元情報はここです。
http://developer.apple.com/library/ios/#documentation/DeveloperTools/Reference/UIAutomationRef/_index.html

その他関連記事です。
http://kray.jp/blog/ui-automation/
http://d.hatena.ne.jp/nakamura001/20100626/1277516740
http://www.fenrir.co.jp/blog/2010/09/uiautomation.html


あとアラートをキャッチする方法についてちょっとポイントがあります。
こんな感じでキャッチするのですが、最後にディレイを入れとかないと、そのままテストコードが終わっちゃってキャッチできない
ことがありますので要注意です。

UIATarget.onAlert = function onAlert(alert) {
    var title = alert.name();
    // add a warning to the log for each alert encountered
    UIALogger.logWarning("Alert with title '" + title + "' encountered!");
    UIATarget.localTarget().captureScreenWithName("alert_" + (new Date()).UTC());
    // test if your script should handle the alert, and if so, return true
    // otherwise, return false to use the default handler
    return false;
}
target.delay(10.0);