本連載ではAndroidアプリを開発している方のためにテストの基本的なノウハウを解説しています。前回の「Androidアプリ開発でテストを始めるための基礎知識」では、Androidアプリ開発におけるテストの課題を解説し、EclipseとJUnitを使った単体テストのやり方を環境構築やコードの書き方を含め紹介しました。今回は「ビジネスロジック」のテストについて説明していきます。一口にビジネスロジックといっても読者の皆さんが持つ定義は、さまざまかと思います。
本連載ではビジネスロジックを「Androidのシステムに依存しない独立した処理」と定義します。具体的には文字列処理や日付・金額計算などのユーティリティが代表的ですが、ファイルI/O、DBアクセス、ネットワーク通信などの処理も含みます。
Android開発のテスト自動化を考えた場合、ビジネスロジックのテスト自動化から取り組み始めるのが最良です。なぜなら、ビジネスロジックのテストであればAndroidのシステムに依存しない処理なのでテストケースの記述が容易になるからです。そのうえ、デバイスに依存しないため、対応する端末が増えたり対応端末のバージョンアップに対応したりする場合にも、そのままテストケースを実行して妥当性を確認可能です。
ビジネスロジックと比較すると、アクティビティ(Activity)やコンテンツプロバイダ(ContentProvider)、サービス(Service)などAndroid固有のコンポーネントがかかわる処理のテストの場合、システムが自動的に行う処理を考慮してテストを記述しなければなりません。
例えば、Androidのコンポーネントのライフサイクルごとにテストケースを書く場合や、アクティビティのUIテストにおいて、スマートフォンとタブレットで表示するレイアウトを変えるためにテストケースを個別に用意する場合などです。
また、ビジネスロジックのテストケースを記述することで、ビジネスロジックがAndroid固有のコンポーネントから自然と分離されるようになります。そうすると、記述が面倒なAndroid固有のコンポーネントにかかわる処理のテストケースが自然と減ります。
なお、上記のような、Android固有のコンポーネントがかかわる処理のテストについて気になる読者の方も多いかと思います。UIのテストに関しては第3回、DBのテストに関しては第4回の連載、また、ネットワーク通信に関しては第5回の連載でMockを利用したテストとしてお伝えする予定です。
Androidアプリをテストする場合に通常のJava開発を実施したことがある方であれば、普通にEclipse上でJUnitを利用してテストしたいと思います。しかし、Android SDKの本体であるandroid.jarの実装は実行時例外をスローするだけの「はりぼて」です。そのため、テストを実行してもすべて失敗してしまいます。
テストを正しく実行するには、正しく実装されたandroid.jarがあるエミュレータやデバイス上に実行ファイルをデプロイしてテストする必要があります。さらに、アクティビティなどライフサイクルを持ったコンポーネントをテストしたい場合は、通常は自分でライフサイクルを制御できないので、Android Testing Frameworkに頼る必要があります。
なお、サードパーティのAndroid向けTesting Frameworkも多数公開されていますが、基本はまずSDK付属のAndroid Testing Frameworkを利用して、テストを自動化します。標準のもので機能が足りない場合は後述するサードパーティのTesting Frameworkの採用を検討するとよいでしょう。
SDK付属のAndroid Testing FrameworkはJUnit 3.8系がベースとなっています。JUnitのTestCaseクラスを拡張したクラスを利用することで、Android固有のクラスのテストが可能です。もちろん、Android固有でないクラスのテストも可能です。
詳細は後述しますが、Android Testing FrameworkにはAndroid特有のコンポーネント(Activity、Service、ContentProviderなど)のテストが簡単にできるように、JUnitの「TestCase」クラスを拡張したものが用意されています。これらの拡張されたTestCaseを使ってテストを記述すると、ボタンを押したときに発生するイベントであるキーイベントを発行したり、コンポーネントのライフサイクルを制御したりすることも可能です。
Android Testing FrameworkではInstrumentationを利用することにより、Android特有のコンポーネントのライフサイクルを制御したり、キーイベントを送信したりすることなどができます。この機能により、受け入れテストのようなUIテストの自動化が可能となっています。
テストはコマンドラインでも実行可能です。コマンドの詳細は「Testing from Other IDEs | Android Developers」を参考にしてください。
テストメソッドには、「@SmallTest」「@MediumTest」「@LargeTest」といったアノテーションを付けることができます。これらのアノテーションはコマンドラインでテストを実行する際に、どのアノテーションのテストメソッドまで実行するか指定するために使用します。
つまり、すべてのテストを実行すると時間がかかる場合、@SmallTestアノテーションが付いたテストは毎回実行して、@LargeTestアノテーションまでのテストは1日に1回だけ実行するなどの使い方が考えられます。そのため、これらのアノテーションを使い分けるガイドラインを事前に決めておくとテストがスムーズに進むようになります。
また、パッケージを指定して、指定したパッケージ以下のテストを実行することも可能です。その他にも色々なオプションがありますが、詳細は上記ページを参照してください。
Pythonで記述したコードからAndroidデバイスやエミュレータを制御する「monkeyrunner」や、負荷テストに利用する「Monkey」といったツールも公開されていますので、利用を検討するとよいでしょう(参考:Monkey - UI / アプリ エクササイザ - ソフトウェア技術ドキュメントを勝手に翻訳)。
次ページでは、Android SDKが提供するTestCaseについて解説し、TestCaseを使ってビジネスロジックのテストを書いて実行します。
サードパーティのAndroid向けTesting Frameworkは以下に記載するプロダクトが有名です。これらのプロダクトは標準のTesting Frameworkで機能が足りない場合に使用を検討します。
【1】UIテストを自動化する「nativedriver」
nativedriverは、WebアプリのUIテストを自動化するためのAPI仕様である「WebDriver」の実装ですが、WebアプリではなくネイティブアプリのUIを操作可能です。
iOS版や、Windows版(2011年12月時点ではプロトタイプフェイズ)も提供されています。標準のAndroid Testing FrameworkでもUIの操作は可能ですが、別プロセスに含まれるUIを操作できないなどの制限があります。nativedriverを利用すると、その操作が可能となります。
【2】ブラックボックステストを自動化する「robotium」
robotiumは、Androidアプリのブラックボックステストを自動化するためのTesting Frameworkです。複数のアクティビティ間のテストを容易に記述できるため、主に機能テスト、システムテスト、受け入れテストに向いています。
【3】エミュレータを使わずモックを動かす「Robolectric」
Robolectricは、テストをエミュレータやデバイス上にデプロイしなくても実行できるように、JavaVM上でAndroid SDKのモックを動かせるTesting Frameworkです。
ユニットテスト実行時に、テスト対象プロジェクトやテストプロジェクトをエミュレータやデバイスにデプロイするのは時間がかかるのでテスト実行時のストレスになりがちです。このフレームワークを利用するとその時間が短縮されるので、ストレスが軽減されます。
【4】robotiumが、さらに便利に「SCIROCCO」
robotiumがベースのUIテスト自動化ツールです。複数のデバイスでテストを実行したり、スクリーンショットを保存してテストレポートを出力できます。
Copyright © ITmedia, Inc. All Rights Reserved.