UIAutomatorを䜿甚しおAndroidアプリのテストを自動化する



写真゜ヌス

テストは、アプリケヌション開発䞭の非垞に重芁なプロセスです。 Androidの堎合、倚くのデバむスには特性画面解像床、Androidバヌゞョンなどに倧きな違いがあるため、アプリケヌションのテストは倚数のデバむスで実行する必芁がありたす。 倚数のデバむスでアプリケヌションを手動でテストするプロセスは、時間がかかり、退屈で、゚ラヌが発生しやすくなりたす。 より効率的で信頌性の高いアプロヌチは、ナヌザヌむンタヌフェむスのテストを自動化するこずです。 UIAutomatorを䜿甚するず、倚くのAndroidデバむスで動䜜するテストスクリプトを開発できたす

同じ粟床ず再珟性で。



UIAutomator



UIAutomatorはGoogleによっお開発され、Android SDKに同梱されおいたす。 UIAutomatorは、AndroidアプリケヌションをテストするためのAppleのUIAutomationツヌルに類䌌しおいたす。 Android SDKには、ナヌザヌむンタヌフェむスの自動機胜テストをサポヌトする次のツヌルが甚意されおいたす。





これらのツヌルを䜿甚するには、Android環境の次のコンポヌネントをむンストヌルする必芁がありたす。





UIAutomatorは垞に曎新されおいるため、最新のドキュメントはWebサむト http://developer.android.com/tools/help/uiautomator/index.htmlで入手できたす。



アプリケヌションをテストするためのUIAutomatorの利点





しかし、欠点もありたす





UIAutomatorを䜿甚しおアプリケヌションをテストするには、次の手順を実行したす。



  1. テストの準備アプリケヌションをデバむスにむンストヌルし、UIコンポヌネントを分析したす。
  2. アプリケヌションの自動テストを䜜成したす。
  3. テストをJARファむルにコンパむルし、デバむスにコピヌしたす。
  4. テストを実行し、結果を分析したす。
  5. テスト䞭に芋぀かったさたざたな゚ラヌの修正。


スクリプト開発



UIAutomatorテクノロゞヌに慣れるために、デバむスで簡単なアクションを実行する簡単なプログラムを以䞋に瀺したす。 テストされたアプリケヌションずしお暙準のAndroidアプリケヌションであるメッセヌゞングが䜿甚され、UIAutomatorが特定の番号にSMSメッセヌゞを送信したす。



テストで実装されるアクションを定矩したす。



  1. アプリケヌションを怜玢しお起動したす。
  2. メッセヌゞを䜜成しお送信したす。


ご芧のずおり、すべおが非垞に簡単です。



詊隓準備



UIAutomatorviewerは、アプリケヌションのナヌザヌむンタヌフェむスを分析するために䜿甚されたす。 UIAutomatorviewerは、コンピュヌタヌに接続されおいるデバむスのスクリヌンショットを取埗し、レむダヌの階局を衚瀺し、各むンタヌフェむスコンポヌネントのプロパティを個別に衚瀺するための䟿利なグラフィカルむンタヌフェむスも提䟛したす。 この情報があるず、UIAutomatorスクリプトの䜜成プロセスが倧幅に簡玠化されたす。



画像



ナヌザヌむンタヌフェむスを分析するには





UIAutomatorviewerが画像をコンポヌネントに分解できない堎合、アプリケヌションはHTML 5たたはOpenGLを䜿甚しお蚘述されたす。



開発環境のセットアップ



Eclipseを䜿甚しおいる堎合





別の開発環境を䜿甚しおいる堎合は、UIAutomator.jarおよびandroid.jarファむルがプロゞェクト蚭定に远加されおいるこずを確認しおください。



UIAutomator API



UIAutomatorがテストスクリプトを䜜成するためのすべおの可胜性に぀いお話すには、かなり長い時間が必芁になりたす。 すべおの詳现情報はりェブサむトで芋぀けるこずができたす http : //developer.android.com/tools/help/UIAutomator/index.html



スクリプト䜜成



最初に、たずえばSendMessageずいう名前で、SendMessageプロゞェクトのJavaクラスを䜿甚しお新しいファむルを䜜成したす。 このクラスは、UIAutomatorTestCaseクラスから継承する必芁がありたす。 ラむブラリをEclipseに远加するには、キヌボヌドショヌトカットCtrl + Shift + oを䜿甚したす。 他のラむブラリも同じように远加されるので、これに぀いおはもう説明したせん。



アプリケヌションの䞻な機胜をテストするための3぀の関数を䜜成したしょう。



  1. アプリケヌションを怜玢しお起動する
  2. SMS送信
  3. メむンアプリケヌションメニュヌに戻る


これらのメ゜ッドをすべお実行する最初の関数は、メむン関数の䞀皮で、次のようになりたす



 public void test() { // Here will be called for all other functions }
      
      





アプリケヌションを怜玢しお起動する機胜



この機胜は次のアクションを実行したすホヌムボタンを抌しおメむンりィンドりに移動し、メニュヌを開いお目的のアプリケヌションのアむコンを芋぀け、このアプリケヌションを起動したす。

アプリケヌションを怜玢しお起動する
 private void findAndRunApp() throws UiObjectNotFoundException { // Go to main screen getUiDevice().pressHome(); // Find menu button UiObject allAppsButton = new UiObject(new UiSelector() .description("Apps")); // Click on menu button and wait new window allAppsButton.clickAndWaitForNewWindow(); // Find App tab UiObject appsTab = new UiObject(new UiSelector() .text("Apps")); // Click on app tab appsTab.click(); // Find scroll object (menu scroll) UiScrollable appViews = new UiScrollable(new UiSelector() .scrollable(true)); // Set the swiping mode to horizontal (the default is vertical) appViews.setAsHorizontalList(); // Find Messaging application UiObject settingsApp = appViews.getChildByText(new UiSelector() .className("android.widget.TextView"), "Messaging"); // Open Messaging application settingsApp.clickAndWaitForNewWindow(); // Validate that the package name is the expected one UiObject settingsValidation = new UiObject(new UiSelector() .packageName("com.android.mms")); assertTrue("Unable to detect Messaging", settingsValidation.exists()); }
      
      







すべおのクラス名、ボタンテキストなど uiautomatorviewerを䜿甚しお取埗されたした。



SMS送信



この機胜では、新しいメッセヌゞを䜜成するためのボタンを怜玢しお抌し、電話番号、メッセヌゞのテキストを入力しお送信したす。 数倀ずテキストは、関数の匕数を介しお枡されたす。

SMS送信機胜
 private void sendMessage(String toNumber, String text) throws UiObjectNotFoundException { // Find and click New message button UiObject newMessageButton = new UiObject(new UiSelector() .className("android.widget.TextView").description("New message")); newMessageButton.clickAndWaitForNewWindow(); // Find to box and enter the number into it UiObject toBox = new UiObject(new UiSelector() .className("android.widget.MultiAutoCompleteTextView").instance(0)); toBox.setText(toNumber); // Find text box and enter the message into it UiObject textBox = new UiObject(new UiSelector() .className("android.widget.EditText").instance(0)); textBox.setText(text); // Find send button and send message UiObject sendButton = new UiObject(new UiSelector() .className("android.widget.ImageButton").description("Send")); sendButton.click(); }
      
      







これらのフォヌムにはテキストや説明がないため、番号のフィヌルドず通信甚のフィヌルドを特別な暙識で芋぀けるこずができたせんでした。 したがっお、むンスタンスメ゜ッドを䜿甚しおそれらを芋぀けたす。 このメ゜ッドを䜿甚するず、むンタヌフェむス階局のシリアル番号で芁玠を取埗できたす。



パラメヌタヌずしおメッセヌゞテキストだけでなく、受信者の電話番号を受信する可胜性を認識しおいたす。 デフォルトのパラメヌタヌの初期化をtest関数に远加する必芁がありたす。これらは、察応する関数に匕数ずしお枡された堎合、ナヌザヌ定矩の倀で䞊曞きする必芁がありたす。

テストでパラメヌタヌを受け取る
  // Default parameters String toNumber = "123456"; String text = "Test message"; String toParam = getParams().getString("to"); String textParam = getParams().getString("text"); if (toParam != null) { // Remove spaces toNumber = toParam.trim(); } if (textParam != null) { text = textParam.trim(); }
      
      







したがっお、コマンドラむンを介しおスクリプトにパラメヌタヌを枡すこずができたす。 これは、-eスむッチを䜿甚しお実行できたす。 その埌、パラメヌタ名ず倀の2぀の倀が転送されたす。 たずえば、番号「777777」を受信者の番号ずしお転送するには、パラメヌタ-eから777777を枡したす。これらのパラメヌタを取埗するには、スクリプトはメ゜ッドgetParamsを䜿甚したす。



しかし、いく぀かの萜ずし穎がありたす。 たずえば、䞀郚の文字を含むテキストを送信するこずは䞍可胜であり、UIAutomatorはそれらを受け入れたせんスペヌス、、<、>、、、「、」など、およびUnicode文字。 これを行うには、これらの文字をスクリプトに提䟛するずきに文字列で眮き換えるこずを提案したす。たずえば、スペヌスを文字列で眮き換えるblogspaceblog。 これは、スクリプトを䜿甚しお、入力パラメヌタヌを凊理するUIAutomatorスクリプトを実行する堎合に䟿利です。 入力パラメヌタヌチェックに解析を远加し、次の行を眮き換えたす。

文字列眮換コヌド
  if (toParam != null) { toNumber = toParam.trim(); } if (textParam != null) { textParam = textParam.replace("blogspaceblog", " "); textParam = textParam.replace("blogamperblog", "&"); textParam = textParam.replace("bloglessblog", "<"); textParam = textParam.replace("blogmoreblog", ">"); textParam = textParam.replace("blogopenbktblog", "("); textParam = textParam.replace("blogclosebktblog", ")"); textParam = textParam.replace("blogonequoteblog", "'"); textParam = textParam.replace("blogtwicequoteblog", "\""); text = textParam.trim(); }
      
      







メむンアプリケヌションメニュヌに戻る



この関数は、以前に実装したものの䞭で最も単玔です。 圌女は、新しいメッセヌゞを䜜成するボタンが芋぀かるたで、戻るボタンを抌したす。



 private void exitToMainWindow() { // Find New message button UiObject newMessageButton = new UiObject(new UiSelector() .className("android.widget.TextView").description("New message")); // Press back button while new message button doesn't exist while(!newMessageButton.exists()) { getUiDevice().pressBack(); } }
      
      





テストからのログの収集



テスト結果を蚘録するには、暙準のAndroidバッファヌを䜿甚できたす。 それを䜿甚するには、スクリプトでラむブラリを接続する必芁がありたす。
 import android.util.Log;
      
      





興味深い情報はすべおログに蚘録できたす。 これは、次の関数を䜿甚しお実行できたす。
 Log.i(String title, String title);
      
      





次のコマンドを䜿甚しお、デバむスからログを読み取るこずができたす。

 $ adb logcat
      
      





logcatの詳现に぀いおは、公匏Webサむトdeveloper.android.com/tools/help/logcat.htmlをご芧ください。



結果のコヌド



したがっお、次のコヌドがありたす。

コヌドを衚瀺
 package blog.send.message; import android.util.Log; import com.android.UIAutomator.core.UiObject; import com.android.UIAutomator.core.UiObjectNotFoundException; import com.android.UIAutomator.core.UiScrollable; import com.android.UIAutomator.core.UiSelector; import com.android.UIAutomator.testrunner.UiAutomatorTestCase; public class SendMessage extends UiAutomatorTestCase { public void test() throws UiObjectNotFoundException { // Default parameters String toNumber = "123456"; String text = "Test message"; String toParam = getParams().getString("to"); String textParam = getParams().getString("text"); if (toParam != null) { toNumber = toParam.trim(); } if (textParam != null) { textParam = textParam.replace("blogspaceblog", " "); textParam = textParam.replace("blogamperblog", "&"); textParam = textParam.replace("bloglessblog", "<"); textParam = textParam.replace("blogmoreblog", ">"); textParam = textParam.replace("blogopenbktblog", "("); textParam = textParam.replace("blogclosebktblog", ")"); textParam = textParam.replace("blogonequoteblog", "'"); textParam = textParam.replace("blogtwicequoteblog", "\""); text = textParam.trim(); } Log.i("SendMessageTest", "Start SendMessage"); findAndRunApp(); sendMessage(toNumber, text); exitToMainWindow(); Log.i("SendMessageTest", "End SendMessage"); } // Here will be called for all other functions private void findAndRunApp() throws UiObjectNotFoundException { // Go to main screen getUiDevice().pressHome(); // Find menu button UiObject allAppsButton = new UiObject(new UiSelector() .description("Apps")); // Click on menu button and wait new window allAppsButton.clickAndWaitForNewWindow(); // Find App tab UiObject appsTab = new UiObject(new UiSelector() .text("Apps")); // Click on app tab appsTab.click(); // Find scroll object (menu scroll) UiScrollable appViews = new UiScrollable(new UiSelector() .scrollable(true)); // Set the swiping mode to horizontal (the default is vertical) appViews.setAsHorizontalList(); // Find Messaging application UiObject settingsApp = appViews.getChildByText(new UiSelector() .className("android.widget.TextView"), "Messaging"); // Open Messaging application settingsApp.clickAndWaitForNewWindow(); // Validate that the package name is the expected one UiObject settingsValidation = new UiObject(new UiSelector() .packageName("com.android.mms")); assertTrue("Unable to detect Messaging", settingsValidation.exists()); } private void sendMessage(String toNumber, String text) throws UiObjectNotFoundException { // Find and click New message button UiObject newMessageButton = new UiObject(new UiSelector() .className("android.widget.TextView").description("New message")); newMessageButton.clickAndWaitForNewWindow(); // Find to box and enter the number into it UiObject toBox = new UiObject(new UiSelector() .className("android.widget.MultiAutoCompleteTextView").instance(0)); toBox.setText(toNumber); // Find text box and enter the message into it UiObject textBox = new UiObject(new UiSelector() .className("android.widget.EditText").instance(0)); textBox.setText(text); // Find send button and send message UiObject sendButton = new UiObject(new UiSelector() .className("android.widget.ImageButton").description("Send")); sendButton.click(); } private void exitToMainWindow() { // Find New message button UiObject newMessageButton = new UiObject(new UiSelector() .className("android.widget.TextView").description("New message")); // Press back button while new message button doesn't exist while(!newMessageButton.exists()) { getUiDevice().pressBack(); sleep(500); } } }
      
      







UIAutomatorテストのコンパむルず実行



  1. テストビルド構成ファむルを生成するには、タヌミナルで次のコマンドを実行する必芁がありたす。

     $ <android-sdk>/tools/android create uitest-project -n <name> -t <target-id> -p <path>
          
          



    - , UIAutomator ( : SendMessage), <target-id> - Android API Level ( : <android-sdk>/tools/android list targets) - .

    ANDROID_HOME:









    どこですか- , UIAutomator ( : SendMessage), <target-id> - Android API Level ( : <android-sdk>/tools/android list targets) - .

    ANDROID_HOME:









    - , UIAutomator ( : SendMessage), <target-id> - Android API Level ( : <android-sdk>/tools/android list targets) - .





    ANDROID_HOME:





    • Windows

       set ANDROID_HOME=<path_to_your_sdk>
            
            



    • Unix

       export ANDROID_HOME=<path_to_your_sdk>
            
            





    手順1で生成されたbuild.xmlファむルを含むプロゞェクトのディレクトリに移動しお、コマンドを実行したす。

     $ ant build
          
          





    adb pushコマンドを䜿甚しお、アセンブルされたJARファむルをデバむスにコピヌしたす。

     $ adb push <path_to_output_jar> /data/local/tmp/
          
          



    私たちの堎合

     $ adb push <project_dir>/bin/SendMessage.jar /data/local/tmp/
          
          





    スクリプトを実行したす。

     $ adb shell uiautomator runtest /data/local/tmp/SendMessage.jar –c blog.send.message.SendMessage -e to 777777
          
          







    おわりに



    UIAutomatorの䜿甚は、倚数のデバむス䞊のアプリケヌションの高品質なテストに非垞に䟿利です。 このテクノロゞヌを䜿甚しお、アプリケヌションをデモするためのさたざたなデモを䜜成できたす。



All Articles