-
Notifications
You must be signed in to change notification settings - Fork 351
2.11. テスト
この章では、ユニットテストとシナリオテストについて解説します。
参考:Testing Fundamentals | Android Developers
参考:Activity Testing | Android Developers
参考:Service Testing | Android Developers
参考:Content Provider Testing | Android Developers
参考:UI Testing | Android Developers
参考:What To Test | Android Developers
Android では、アプリ本体のプロジェクトと、テストケース用のプロジェクトが分離されています。
テストプロジェクトのセットアップは、Eclipse 上から実行することができます。
File > New から、Project... または Other... を選択してください(Ctrl + N または Command + N)。
新規プロジェクトの画面から、Android > Android Test Project を選択します。
Launch Test Project Wizard
次に、テストプロジェクトのセットアップをします。
テストプロジェクトの名前と、配置場所を指定します。
Test Project Configuration
次に、テストのターゲットとするアプリ本体のプロジェクトを選択します。
Select target
最後に、テストプロジェクトが利用する SDK のバージョンを選択して完了です。
Select SDK Version
このテストプロジェクトを用いて、ユニットテストや、シナリオテストを記述していきます。
Android では、フレームワーク自身がユニットテストのフレームワークを持っています。
このフレームワークは、JUnit3 をベースにしています。
テスト対象に応じて、独自に拡張されたテストケースクラスが用意されています。
一般的な、Android のテストケースクラスです。
Context、特にActivityのContextを必要とするクラスのテストをするために作られています。
これによって、リソースへのアクセスも可能となっています。
テストケースは、メソッドごとに定義します。
この時、メソッド名の命名規則として、先頭に必ずtestと記述する必要があります(JUnit3 の仕様)。
また、テストケースは、記述した順に実行されるとは限りません。
テストケースを実行するごとに、前準備と後始末をするためのメソッドも用意されています。
それぞれ、事前準備をするメソッドはAndroidTestCase#setUp()、後始末をするメソッドはAndroidTestCase#tearDown()です。
特に、テスト内でファイル I/O やデータベース接続などのリソースを扱う場合は、後始末をするtearDown()で、必ずリソースのクローズを行うようにします。
以下に、テストのターゲットとするクラスのサンプルと、そのターゲットをテストするサンプルを示します。
public class SampleTestTarget1 { public int add(int left, int right) { return left + right; } public int div(int left, int right) { if (right == 0) throw new IllegalArgumentException("right operand must not be zero."); return left / right; } }
public class MyTestCase extends AndroidTestCase { // テストの前準備のメソッド。テストケースの実行ごとに呼ばれる。 // 事前準備中に何らかの例外が起こる可能性があるので、例外をスローする宣言をする。 @Override protected void setUp() throws Exception { super.setUp(); } // テストの後始末のメソッド。テストケースの実行ごとに呼ばれる。 // 後始末中に何らかの例外が起こる可能性があるので、例外をスローする宣言をする。 @Override protected void tearDown() throws Exception { super.tearDown(); } // テストケース本体。名前は必ず test から始まる // テスト中に異常が発生した場合(=例外がスローされた場合)、テストを Fail とするためその例外をそのまま投げるようにする public void testAdd() throws Exception { SampleTestTarget1 target = new SampleTestTarget1(); // 第 1 引数 に期待値、第 2 引数に実際の計算を入れて、等しいかどうか比較する assertEquals(2, target.add(1, 1)); assertEquals(3, target.add(1, 2)); assertEquals(4, target.add(2, 2)); } public void testDivide() throws Exception { SampleTestTarget1 target = new SampleTestTarget1(); assertEquals(2, target.div(4, 2)); try { target.div(1, 0); // 期待した例外が来ない場合、強制的に Fail する fail("no argument checking!?"); } catch (IllegalArgumentException e) { // 例外をテストする場合。 // テストしたい例外のみをキャッチして、それ以外は throws 宣言で Fail 扱いとする // テストしたい例外をキャッチした上で、何もしなければ Pass 扱いとなる } } }
テストで利用する、検証用のメソッドは以下のようなものがあります。
引数を 2 つとるメソッドは、第 1 引数が期待する値、第 2 引数が実際にテスト対象を呼び出した結果を渡すようにします。
| メソッド | 用途 |
|---|---|
assertEquals() |
第 1 引数と第 2 引数が等しいかどうか |
assertNull() |
引数のオブジェクトがnullかどうか |
assertNotNull() |
引数のオブジェクトがnullでないかどうか |
assertTrue() |
引数のbooleanがtrueかどうか |
assertFalse() |
引数のbooleanがfalseかどうか |
assertSame() |
第 1 引数と第 2 引数が、同じオブジェクトを参照しているかどうか |
assertNotSame() |
第 1 引数と第 2 引数が、同じオブジェクトを参照していないかどうか |
ContentProviderのためのテストケースです。
Serviceのためのテストケースです。
Contextをモックするための仕組みとして、MockContextクラスが用意されています。
このクラス自身は、どのメソッドを読んでも、UnsupportedOperationExceptionを投げるだけになっており、自分でモックしたい部分や、モックすべき部分を、MockContextを継承して記述し、各テストケースクラスで、そのContextを注入して使います。
ユニットテストでは、各クラス(特にモデルのクラス)が適切な振る舞いをするかどうかをテストしました。
シナリオテストでは、ボタンを押したり、画面を回転した時に、アプリがどのように振る舞うかをテストします。
これを機能テストとも呼んだりしています。
Activity に対して、テストプロジェクトから様々な操作を行うためのテストケースクラスです。
ActivityInstrumentationTestCase だけでは足りない、より幅広い UI のテストをするためのフレームワークです。
ADT リビジョン 21 以降から導入され、Android 4.1 以降で動作するように作られた、UI のテストフレームワークです。
Android SDK に含まれています。