#freeze [[FrontPage]] #contents 2011/08/17からのアクセス回数 &counter; ** Automation [#m2bfd6fd] [[titanium/単体テスト(QUnit)を試す]]では、データベース廻りの単体テストを紹介しましたが、 今回は、XCodeに付属するAutomationを使ったUIのテスト方法について説明します。 *** 起動方法 [#g31fd2f1] Automationは、XCodeのInstrumentsのライブラリとして提供されています。 - /Developer/Applications以下のInstrumentsを起動します - Chooseダイアログが表示されますので、Automationを選択します &ref(choose_dialog.png); - Choose Targetメニューから「Choose Target...」でターゲットを選択します、ここではTitanium mobileで作成したDemoアプリを選択します &ref(choose_target.png); - デフォルトでは、iPad - Simulator- iOS 3.2となっているので、ターゲットのiOSにします ((Automationは、iOS4以降でないと使えません)) &ref(lunch_option.png); ** UIのテスト [#i56ad3a6] *** テストスクリプトの設定 [#cf18d39d] Automationのテストは、javascriptで記述したスクリプトに沿って行われます。 Scriptのタグで使用するスクリプトをセットします。ここではautomation_test.jsをセットします。 *** 最初のスクリプト [#zcfbb59f] 最初に、ログの出力と部品の構成を出力するスクリプトを実行します。 #pre{{ UIALogger.logStart("Starting Test"); UIALogger.logStart("Logging Tab1 element tree …"); UIATarget.localTarget().logElementTree(); UIALogger.logPass(); }} - UIALogger.logStartでロググループの開始をログ出力 - logElementTreeで部品の構成を表示 - UIALogger.logPassでグループの処理の成功をログ出力 しています。スクリプトの実行は、Recordボタンを押した後にStart Scriptボタンを押します。 ((Run on Recordを選択すると、StartScriptボタンを押さなくても自動的にスクリプトが実行されます)) テストの画面は、 &ref(iPhone.png); 出力結果は、 &ref(log1.png); これでは、良く分からないので、このログの階層構造を示すと以下のようになります。 &ref(UI階層.png); *** 部品へのアクセス [#v544fccd] [[Automation Reference Collection>http://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/UIAutomationRef.pdf]]((GoogleでUIAutomationRefとするとでてきます)) に各部品へのアクセス方法が載っています。 すべてのUI部品が、UIAElementクラスのサブクラスとなっているので、部品が含む要素は、buttons()等のように部品要素単位で取得することができます。 logElementTreeで正確な画面の構成が取得できるので、これを元に部品にアクセスします。 最初のスクリプトにタブバーのTab 1ボタンの名前を出力してみます。 #pre{{ var target = UIATarget.localTarget(); var app = target.frontMostApp(); var main = app.mainWindow(); var navi = main.navigationBar(); var tab = main.tabBar(); UIALogger.logDebug(tab.buttons()[0].name()); }} - 最初にtarget, app, main, navi, tabにターゲット、アプリケーション、メインウィンドウ、ナビゲーションバー、タブバーをセットします - tab.buttons()[0].name()でタブバーのボタン配列の1個目のボタンの名前を取得し、logDebugでログに出力します 実行結果は、以下の通りです。 &ref(log2.png); *** 画面遷移 [#j2d4d042] 次に画面遷移ですが、通常の操作通り、部品をタップ(tap関数)して画面を遷移します。 Tab 2のWebViewのFoodLogサイト画面に遷移してみます。 Webページの表示に時間がかかるので、delay関数ですこし待ちます。 #pre{{ tab.buttons()["Tab 2"].tap(); target.delay(3.0); UIALogger.logStart("Logging Tab2 element tree …"); main.logElementTree(); UIALogger.logPass(); }} &ref(FoodLog.png); ログの結果、WeViewの中身の要素も通常の要素と同じように表示されていることが分かります。 ((WebViewの画面遷移もAutomationから操作できるので、この結果はとても重要なことです)) &ref(log3.png); また、tapの直後はmain.logElementTreeが正しく表示されませんので、delay関数で少し時間を 置くのを忘れないようしてください。 *** テストシナリオの実行 [#k201d2a0] 画面の切り替えができたので、テストシナリオに沿った動作をさせてみましょう。 - 初期画面 - FoodLog画面切り替え - 記録の追加 - グラフの表示 以上の処理をスクリプトにすると記録の追加は、 #pre{{ // Tab 1に戻り tab.buttons()["Tab 1"].tap(); target.delay(2.0); // 追加ボタンを押す navi.buttons()["Add"].tap(); target.delay(0.5); // 体重を入力 main.textFields()[1].setValue("63.5"); target.delay(1.0); main.buttons()["この値で保存する"].tap(); target.delay(1.0); }} となり、グラフ表示は、 #pre{{ // グラフを表示 navi.buttons()["Graph"].tap(); target.delay(1.0); }} となります。 ** テスト動画 [#g9fda2a8] 実際にiPhoneシミュレータで実行している動画をアップします。 #youtube(Gw81mf1GaWE); 上記デモに使ったテストスクリプト - &ref(automation_test.js); ** コメント [#ybfa47f3] #vote(おもしろかった[3],そうでもない[0],わかりずらい[0]) #vote(おもしろかった[4],そうでもない[0],わかりずらい[0]) 皆様のご意見、ご希望をお待ちしております。 #comment_kcaptcha