はじめに
Androidアプリケーション開発者にでっかいクリスマスプレゼント?が投げ込まれましたー。
Espressoが2.0にバージョンアップすると共に、Android Support Library の一部として取り込まれ、JUnit4がサポートされました!!
Espresso 2.0 is here!: Google+
Espresso 2.0 が Android support library の一部としてリリースされた
SDK ManagerでAndroid Support RepositoryをインストールすればEspressoのjarをlib等に置くことなく使えるということかな?(まだ試してません・・・)
(参考)こちらも併せてどうぞ
Setup
変更点
# Esporesso1.1までの書き方
androidTestCompile files('libs/espresso-1.1-bundled.jar')
androidTestCompile files('libs/testrunner-1.1*.jar')
" 2.0~の書き方
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
// ~1.1
com.google.android.apps.common.testing.ui.espresso
// 2.0~
android.support.test.espresso
サンプル
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.my.awesome.app"
minSdkVersion 10
targetSdkVersion 21
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
...
}
dependencies {
// App's dependencies, including test
compile 'com.android.support:support-annotations:21.0.3'
// Testing-only dependencies
androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
}
AndroidJUnitRunnerについて
ざっくりですが、Espresso 2.0 で導入された AndroidJUnitRunner
のオフィシャルWikiのJUnit4関連部分を抜粋・意訳しました。
誤訳等あったらごめんなさい。
以下翻訳
JUnit4
(訳注: このセクションはほとんどJUnit4自体の説明なので知っている人は読み飛ばしてください。特に後半のアノテーションの説明。)
AndroidJUnitRunner
は、JUnit3と完全な上位互換性を保ちながらJUnit4に完全対応しています。AndroidRunnerBuilder はJUnitの AllDefaultPossibilitiesBuilder を継承しておりJUnit3とJUnit4の両方のテストを収集するため、既存のJUnit3のテストを書き換えることなく、Junit4の新たなテストを書くことができます。
注意:一つのクラス内に、JUnit3方式とJUnit4方式のテストを混ぜないでください。
JUnit4のテストには @RunWith(AndroidJUnit4.class)
アノテーションをつけてください。AndroidJUnitRunner
は全てのJUnit4アノテーションをサポートしており、テストの実行やコーディングがより簡単で理解しやすくなります。
よく使うアノテーションを挙げましょう。
-
@Test
アノテーションは、JUnit3のtestXXXプレフィックスの代替機能です。JUnit4のテストクラスはTestCase
クラスを継承する必要はありませんし、継承するとJUnit3のテストとして扱われます。 -
@Test(expected=IllegalArgumentException.class)
。JUnit4では@Test
アノテーションの後ろに期待するパラメータを書くことで、コード量を減らせます(訳注: 原文の toredudes は to reduces のタイポ??自信なし)。JUnit3では以下のようなコードでした。
try{
foo.bar();
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {}
-
@Before
はJUnit3のsetUp()
メソッドに相当し、各テストメソッドの実行前に呼び出されます。テストフィクスチャのセットアップ等に使います。複数の@Before
メソッドがあってもよいですが、呼び出し順は一定ではありません。 -
@After
はtearDown()
に相当し、各テストメソッド終了時に実行されます。リソース解放に使いましょう。 -
@BeforeClass
はテストクラス毎に一度だけ呼び出されます。DB接続などコストのかかる処理に使うとよいでしょう。 -
@AfterClass
はクラス内の全テストメソッド実行後に呼ばれます。 BeforeClassで作成したリソースの解放に使います。
AndroidテストAPIへの適用
ActivityInstrumentationTestCase2
ActivityInstrumentationTestCase2
のような既存のAndroidテストAPIでJUnit4構文を使うには、次の5ステップを行います。
-
ActivityInstrumentationTestCase2
に@RunWith(AndroidJUnit4.class)
アノテーションを付けます。(訳注: 原文の ! はタイポ??) -
setUp()
メソッドをオーバーライドし、@Before
アノテーションを付け、super.setUp()
を呼び出します。 -
InstrumentationRegistry
を使用して Instrumentation をインジェクトします。以前はInstrumentationTestRunner によりインジェクトされていましたが、手動で行う必要があります。
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
-
AndroidJUnitRunner
に認識させるため、全てのテストに@Test
を付けます。 -
tearDown
をオーバライドし@After
を付け、super.tearDown()
を呼び出します。これはオブジェクトのリークを防ぐために重要です。
ActivityInstrumentationTestCase2
でJUnit4を使った例です。
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MyJunit4ActivityInstrumentationTest
extends ActivityInstrumentationTestCase2<MyActivity> {
private MyActivity mActivity;
public MyJunit4ActivityInstrumentationTest() {
super(MyActivity.class);
}
@Before
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
mActivity = getActivity();
}
@Test
public void checkPreconditions() {
assertThat(mActivity, notNullValue());
// Check that Instrumentation was correctly injected in setUp()
assertThat(getInstrumentation(), notNullValue());
}
@After
public void tearDown() throws Exception {
super.tearDown();
}
}
Instrumentation Thread Handlers
(訳注: よくわかっていないので省略します)
参考
JUnit4についてはこの本が勉強になりました。初心者にもわかりやすかったです。
Androidのテストに関する記述もあって(eclipseベースだったりして)若干古いですが、考え方はいまでも充分役に立ちます。