連載
» 2014年11月05日 18時00分 公開

Androidテストで便利なuiautomatorviewer、UiScrollableの使い方、テキスト入力API制限事項の回避方法スマホ向け無料システムテスト自動化ツール(3)(3/4 ページ)

[外山純生,テスト自動化研究会(STAR)/Androidテスト部]

UiScrollableを使ってスクロールに対応する

スクロール未対応のテストスクリプト

 「今回行うテスト」の章では、事前に「15件」の顧客を登録しておく必要がありますが、その前に「3件」の顧客を登録した状態で動作するテストスクリプト(CustomerModifyTest1クラス)を見てみましょう。

public class CustomerModifyTest1 extends UiAutomatorTestCase {
 
// (省略)
 
    public void test顧客修正_3人_氏名が英語() throws Exception {
        // setup
        // 3件の顧客を追加
        // lastAddedNameには最後に追加した顧客の氏名が入る
        String lastAddedName = addCustomers(3, "John Doe");
    
        // exercise
        String newName = "Jhon Smith";
        MasterPage page = new MasterPage();
        page = page.goDetailPageToModifyCustomer(lastAddedName).typeName(newName).saveAndGoBack();
    
        // verify
        assertTrue("Master画面に[" + newName + "]が見付かりません", page.doesCustomerNameExist(newName));
    }
}

 テストを実行する端末の言語設定を英語にし、IMEを英語入力モードにした上で、以下のコマンドでテストを実行してみてください。テストが成功するはずです。

$ adb shell uiautomator runtest UiautomatorSample.jar -c com.nowsprinting.hellotesting.uiautomator.CustomerModifyTest1

 次に、この「addCustomers(3, "John Doe")」の引数3を15に変更し、「15件」の顧客を登録した状態で動作させてみましょう。今度は以下のように、顧客一覧に「John Doe 14」が見つからないという理由でテストが失敗します。

Error in test顧客修正_3人_氏名が英語:
com.android.uiautomator.core.UiObjectNotFoundException: for text= "John Doe 14"
    at com.android.uiautomator.core.UiCollection.getChildByText(UiCollection.java:125)
    at com.nowsprinting.hellotesting.uiautomator.page.MasterPage.getCustomerItem(MasterPage.java:93)
    at com.nowsprinting.hellotesting.uiautomator.page.MasterPage.goDetailPageToModifyCustomer(MasterPage.java:63)
    at com.nowsprinting.hellotesting.uiautomator.CustomerModifyTest1.test顧客修正_3人_氏名が英語(CustomerModifyTest1.java:67)
    (以下略)

 そのときの端末の画面は以下のようになっています。15件目に登録された顧客「John Doe 14」が画面上に表示されていません。「John Doe 14」を表示させるためには下方向へのスクロールが必要な状態です。

テスト失敗時の画面

 uiautomatorでは、特定・操作したいUIコンポーネントが画面外にある場合は、あらかじめスクロール操作を行い、画面上に表示させておく必要があります。このテストスクリプトでは、スクロール操作なしに画面外の「John Doe 14」を見つけようとしたため、テストが失敗したのです。

スクロール対応版に修正してみる

 テスト失敗の原因となっている、顧客一覧から顧客1件を取り出すテストコードは以下の通りです(MasterPageクラスのgetCustomerItem()メソッド)。これをスクロール対応に修正してみましょう。

/**
 * 顧客名一覧のListViewの中から、指定された顧客名が表示されているリストアイテムを取得する。
 * 
 * @param customerName 検索したい顧客名
 */
protected UiObject getCustomerItem(String customerName) throws UiObjectNotFoundException {
    UiCollection customerList = new UiCollection(new UiSelector().className(ListView.class.getName()));
    return customerList.getChildByText(new UiSelector().className(TextView.class.getName()), customerName);
}

 上記で使われているUiCollectionクラスは、UIコンポーネントの集合(UIコンテナー)を表すクラスで、UIコンテナー内の要素を検索するgetChildByText()メソッドなどが定義されています。ここでは、顧客一覧(ListView)のリストアイテム(TextView)のうち、表示文字列(顧客氏名)がcustomerNameと一致しているものを検索しています。

 uiautomatorでスクロール操作を実現するには、UiScrollableクラスを使います。UiScrollableクラスはUiCollectionクラスのサブクラスとなっているため、UiCollectionを使っているテストスクリプトであれば、以下の二つのステップで簡単にスクロール対応にすることができます。

  • UiCollectionを全てUiScrollableに置き換える
  • UiScrollableインスタンス生成直後に、スクロールする方向によって以下のどちらかのメソッドを呼び出す
// getCustomerItem()のスクロール対応版
protected UiObject getCustomerItem(String customerName) throws UiObjectNotFoundException {
    UiScrollable customerList = new UiScrollable(new UiSelector().className(ListView.class.getName()));
    // スクロール方向を指定する
    customerList.setAsVerticalList();
    return customerList.getChildByText(new UiSelector().className(TextView.class.getName()), customerName);
}

 上記のように修正したgetCustomerItem()を使えば、15件の顧客を追加しても問題なく動作します。UiScrollableは、目的のUIコンポーネントが最初から画面に表示されている場合(スクロール不要な場合)にも対応していますので、件数が増えるとスクロールする可能性のある箇所には、最初からUiScrollableを使うのがお勧めです。

 スクロール対応のテストコードはCustomerModifyTest2クラスに用意してあります(テストコード内部でMasterPageクラスを継承したスクロール対応版のMasterPageScrollSupportクラスを呼び出しています)ので、参考にしてください。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。