環境
- Mac OSX
- IntelliJ IDEA 15
- JUnit 4.x
- Hamcrest
- Mockito 1.10.19
- Espresso 2.2.1
概要
JUnitは、Javaのテスティングフレームワークです。
テストの実行、期待値と実測値の検証、テストケースのフォーマット(アノテーションなど)の機能を持ちますが、実際のテストでは、拡張APIを利用することの方が多いと思います。
JUnit4から、Android SDKに公式サポートされているので、特定のディレクトリにテストコードを配置すれば、意識せずに実行することができてしまいます。(拡張APIもGradleでインストールできるので、こちらも意識せずに利用できてしまいます)
そして、実際にテストコードを書く段階になって、どの機能を誰が提供してくれているのか、わからなくなります。
JUnitと拡張API
- JUnit
- テスティングフレームワーク
- テストが全て成功すると、グリーンバーを表示してくれる。失敗するとレッドバー。(テスト進捗状況に一喜一憂させられる)
- 比較検証を行う『assertThat()』メソッドは、JUnitの機能
- hasItem(), hasItems()は、JUnitMatchersが提供しているが、is()は別ライブラリの機能
String actual = "Hello" + " " + "World";
assertThat(actual, is("Hello World"));
List<String> actual = sut.getList();
assertThat(actual, hasItem("World"))
List<String> actual = sut.getList();
assertThat(actual, hasItems("World"))
- Hamcrest
- Matcherライブラリ
- もともと拡張ライブラリ、JUnit4.4から組み込まれる
- 『is()』メソッドは、HamcrestのMatcherメソッド。その他に以下のメソッドがある
assertThat(actual, is("Hello World"));
assertThat(actual, is(nullValue()));
assertThat(actual, is(not(0)));
assertThat(actual, is(notNullValue()));
assertThat(actual, is(sameInstance(expected)));
assertThat(actual, is(instanceOf(Serializable.class)));
- Mockito
- モック用ライブラリ
- 任意のクラスを指定して、『もし○○だったら、××を返す』と文章的にわかりやすい
- リフレクションを利用して、動的にクラスの内容を書き換えているのだろうけど、使えば使うほど、どうやっているのか不思議なライブラリ
List<String> stub = mock(List.class);
when(stub.get(0).thenReturn("Hello"));
assartThat(stub.get(0), is("Hello"));
- Espresso
- Viewに何が表示されているかのテストが出来る
// TextViewに、my_viewというリソースIDが定義されていて、内容が"Hello!"の場合に成功
onView(allOf(withId(R.id.my_view), withText("Hello!")));
// Viewに対して、クリックなどの操作も出来る
onView(...).perform(typeText("Hello"), click());
// ListView, GridViewの場合には、onView()ではなくonData()を利用する
onData(allOf(is(instanceOf(String.class)), is("Americano"))).perform(click());
Tips
- Espressoでの比較検証の注意点
- 画面上に表示されている要素(R.id.xx)しか取得や比較ができない。
- テストを行う際、画面サイズが異なると、テスト対象になっている要素があったりなかったりする。これがテストの観点(全ての端末で、ある文字列が表示されていること、など)になったりします。
- 同様に、ListView, GridViewなどの後ろの要素の判別は、『perform(scrollTo())』などを利用して、スクロールさせてから判別する必要があります。
- 例えば、ImageViewで任意の画像を表示している場合、ImageViewがあるか、ないかの判別や、Src, Backgroundにセットされているかの判別はできますが、その画像がどういう内容かは判別できません。
Android ユニットテストに関するその他の記事
- Android ユニットテストとUIテストの自動化プラクティス
- Android エミュレーターでのユニットテスト 画面サイズとAPIレベルのマトリクス
- Android ユニットテストとUIテスト