Androidテストで便利なuiautomatorviewer、UiScrollableの使い方、テキスト入力API制限事項の回避方法:スマホ向け無料システムテスト自動化ツール(3)(4/4 ページ)
本連載では、スマートフォン(Android/iOS)アプリ開発における、システムテストを自動化するツールを紹介しています。今回は、Android SDK標準の何でもテストツールuiautomatorの使い方の応用編として、uiautomatorviewer、UiScrollableの使い方、テキスト入力API制限事項の回避方法などを紹介。
テキスト入力APIの制限事項を回避する
uiautomatorのテキスト入力API「UiObject.setText()」は、テストを実行する端末の言語設定が英語で、かつ、IMEが英語入力モードでないと、想定とは異なる文字列が設定されてしまうことがあります。ここでは、その回避方法を紹介します。
テキスト入力フィールドに非ASCII文字を入力する
UiObject.setText()は、仮想的なキーボード(PCで一般的に使われるQWERTYキーボード)をタイプし、対応するキーイベントを端末に送信することで、文字の入力を実現しています。
そのため、QWERTYキーボードでタイプできる文字しか、setText()を使って入力できず、日本語をはじめとする非ASCII文字を引数に指定しても、何も入力できません。
■非ASCII文字の入力を可能にするUiautomator Unicode Input Helper
テキスト入力フィールドに非ASCII文字を入力できるようにするためには、筆者が作成した「Uiautomator Unicode Input Helper」(以降では「UUIH」と書きます)が利用できます。
UUIHはApache License, Version 2.0のライセンスで提供されており、以下のURLからダウンロードできます。
UUIHは2つのモジュールで構成されています。
- Utf7Ime:テストを実行する端末にインストールする特別なIME。テスト実行時にデフォルトのIMEに設定して利用する。このIMEを使うことで、QWERTYキーボードでタイプできる文字の組み合わせから、任意のUnicode文字を入力できる
- ヘルパーライブラリ:日本語などのUnicode文字列を、Utf7Imeが解釈できるASCII文字列に変換するためのライブラリ。uiautomatorのテストスクリプトへソースコードをコピーして利用する
それぞれのモジュールのインストール方法と準備については、UUIHの「README.ja.md」の「準備」の節を参照してください。なお、サンプルのテストスクリプトには、すでにヘルパーライブラリを組み込んであります。
サンプルを動かしたい場合は、Utf7Imeだけをテストを実行する端末にインストールし、デフォルトのIMEに設定してください。
■テストスクリプトの修正
次に、テストスクリプト側で、UiObject.setText()で入力しようとしている文字列について、それぞれ以下のような修正を行います。
UiObject editText = ...; // テキスト入力フィールドを指すUiObject editText.setText("日本語");
UiObject editText = ...; // テキスト入力フィールドを指すUiObject String encodedText = Utf7ImeHelper.e("日本語") editText.setText(encodedText);
上記のように、直接setText()に入力文字列を指定する代わりに、ヘルパーライブラリが提供するUtf7ImeHelper.e()メソッドを使って変換した文字列を指定するようにします。Utf7ImeHelperクラスはjp.jun_nama.test.utf7ime.helperパッケージにあります。
なお、&以外のASCII図形文字しか入力しない箇所については、上記修正は必要ありません(修正しても問題ありません)。
端末の言語設定が英語以外でも動作するようにする
UiObject.setText()は、テキスト入力フィールドが空でない場合に備えて、内部的にUiObject.clearTextField()を呼び出し、テキスト入力フィールドをクリアしてから、引数に指定された文字列を入力するようになっています。
ところが、端末の言語設定が英語以外になっていると、テキストフィールド入力フィールドのクリア処理が正しく動作しません。
例えば、端末の言語設定を日本語にすると、最初に紹介したCustomerModifyTest1クラスのテストも、顧客氏名を修正する箇所で失敗してしまいます。具体的には「John Doe 2」を「John Smith」に修正しようとすると、「John Smith Doe 2」となってしまいます。
uiautomatorは、テキスト入力フィールドをクリアするときに、以下の操作を行っています。
- テキスト入力フィールド内の左端の近くをロングタップ
- アクションバーの[Select all]メニュー(下図の赤丸で囲んだ部分)をタップし、「全て選択」状態にする
- DELETEキーを押し、全ての文字をクリア
端末の言語設定を日本語にすると[Select all]メニューの名前(contentDescription属性)が[全て選択]に変化してしまうため、テキストを全て選択した状態にできず、最初の単語だけがクリアされてしまうのです。
この問題を解決するために、アクションバーのメニュー選択部分のロジックだけを修正した、以下のようなi18nClearTextField()メソッドを用意します。
/** * 引数に指定されたテキスト入力フィールドについて、すでに入力されている文字列をクリアする。 * テストを実行する端末の言語設定が英語以外でも動作する。 * * @param editText 内容をクリアしたいテキスト入力フィールド */ public static void i18nClearTextField(UiObject editText) throws UiObjectNotFoundException { editText.longClickTopLeft(); // "Select all"のリソース文字列を android.R.string.selectAll から取得する。 // この方法で、端末の言語設定に応じた文字列を取得できる。 String selectAllDesc = Resources.getSystem().getString(android.R.string.selectAll); UiObject selectAll = new UiObject(new UiSelector().descriptionContains(selectAllDesc)); if (selectAll.waitForExists(50)) selectAll.click(); SystemClock.sleep(250); UiDevice.getInstance().pressDelete(); }
UiObject.clearText()の代わりに、こちらを呼び出すことで、端末の言語設定が英語以外でも意図通りに動作するようになります。すでに文字列が設定されているテキスト入力フィールドに対してUiObject.setText()したい場合は、その直前に上記メソッドを呼び出してください。
サンプルのテストスクリプトについて
サンプルのテストスクリプトでは、CustomerModifyTest3クラスに、この二つの問題に対応したテストを用意してありますので、参考にしてください。デフォルトのIMEをUtf7Imeにし、端末の言語設定を日本語にしてお試しください。
対応の要となるクラスは、DetailPageUnicodeSupportクラスです。このクラスはDetailPageクラスを継承し、「氏名」欄へ入力するtypeName()メソッドを、日本語対応版になるようにオーバーライドしています。
package com.nowsprinting.hellotesting.uiautomator.page; import com.android.uiautomator.core.UiObjectNotFoundException; import com.nowsprinting.hellotesting.uiautomator.util.CommonUiActions; import jp.jun_nama.test.utf7ime.helper.Utf7ImeHelper; /** * Detail画面を表すクラス(氏名欄のみUnicode文字の入力に対応)。 */ public class DetailPageUnicodeSupport extends DetailPage { @Override public DetailPage typeName(String name) throws UiObjectNotFoundException { if (name != null) { // 国際化対応版のclearTextField()を最初に呼び出す CommonUiActions.i18nClearTextField(mNameTextField); // Utf7Imeが理解できる文字列に変換してからsetTextする mNameTextField.setText(Utf7ImeHelper.e(name)); } return this; } }
次回は、BDDの主要ツールの一つ「Calabash」について
2回にわたって、uiautomatorを紹介しましたが、いかがでしたでしょうか。uiautomatorは、他者が作成したアプリを操作できるという点では非常に強力なツールです。まだ開発途上の部分もありますが、今回紹介したノウハウを活用すれば、連載第1回で紹介した「システムレベルの機能テスト」で必要となる項目の多くを自動化できるはずです。
今回の記事では紹介しきれませんでしたが、アプリの強制終了時など、不意に発生する事象に対しても対応できる「UiWatcher」という仕組みも用意されています。筆者のブログに、使い方を紹介していますので、興味のある方は調べてみてください。
次回はBDD(Behavior-Driven Development/振る舞い駆動開発)の主要ツールの一つである「Calabash」を紹介します。
- iOS/AndroidのUIテストを自動化するAppiumのテストスクリプトの書き方とインスペクターの使い方
- SeleniumのUIテスト自動化をiOS/AndroidにもたらすAppiumの基礎知識とインストール方法、基本的な使い方
- Calabash-Androidのテスト高速化、GPS、スクショ、データ駆動型テスト
- Calabash-AndroidによるBDDの実践とJenkinsによる「Living documentation」
- Calabash-Androidでテストシナリオを作成する方法
- iOS/AndroidにCucumberのBDDをもたらすテストフレームワークCalabashの基礎知識とインストール
- Androidテストで便利なuiautomatorviewer、UiScrollableの使い方、テキスト入力API制限事項の回避方法
- Android SDK標準の何でもテストツールuiautomatorの基本的な使い方
- システムテスト自動化の基礎知識とMonkeyTalkの使い方
著者プロフィール
外山 純生
NTTソフトウェア株式会社勤務。数年前よりAndroidアプリケーション開発にかかわり始めたのを切っ掛けに、Androidにおける自動テストに興味を持つようになる。Android関連プロジェクトに対する技術支援業務に携りながら、Android向けのテストツールがもっと広く使われるようになることを願って、ブログにて技術情報を発信中
Blog:sumioの技術メモ
Twitter:@sumio_tym
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- テスト自動化の歴史と今後、良い/悪い事例〜システムテスト自動化カンファレンス2013レポート
テスト自動化を開発の“武器”にするための3つのポイントや、“自動化”の良い事例、悪い事例など、テストの現場を「進化させる」知見が多数紹介されたカンファンレンスの模様をレポートする。 - ビジネス目標を見据えたテスト設計が肝!「DevOps時代のテスト自動化カンファレンス 冬の陣」開催
DevOpsの実践で肝となるソフトウェアテストの自動化。しかし@ITの読者調査でも50%以上が「テスト環境に課題あり」と回答した。これにどう対応すれは良いのだろうか? カンファレンス登壇者の言葉にヒントを探る。 - Kiwi+CocoaPodsで始めるiOSアプリの振る舞いテスト入門
現代の開発現場において欠かせないCI/継続的デリバリを、iOSアプリ開発に適用するためのツールやノウハウを解説する連載。今回は、iOSアプリの機能の振る舞いをテストするテスティングフレームワークの特長とインストールの仕方、主な使い方を解説します。 - Android SDKでビジネスロジックのテストを自動化するには
- 第2回Androidテスト祭りレポート:Android開発の上層テストで失敗しないためのポイントとは
セキュリティ設計や受け入れテストガイドライン、CIツールJenkins+コードレビューGeritt、テスト効率化ノウハウ、リモートテストサービスなど