続・AndroidでJUnit4を使う方法（Android SDKで正式サポートされました！）

## はじめに
Androidアプリケーション開発者にでっかいクリスマスプレゼント？が投げ込まれましたー。

Espressoが2.0にバージョンアップすると共に、Android Support Library の一部として取り込まれ、JUnit4がサポートされました！！

[Espresso 2.0 is here!: Google+](https://plus.google.com/+AndroidDevelopers/posts/jHXFkebKjEb)
[Espresso 2.0 が Android support library の一部としてリリースされた](http://vividcode.hatenablog.com/entry/android-app/library/espresso-2.0)

SDK ManagerでAndroid Support RepositoryをインストールすればEspressoのjarをlib等に置くことなく使えるということかな？（まだ試してません・・・）

#### （参考）こちらも併せてどうぞ
* [旧・AndroidでJUnit4を使う方法](http://qiita.com/AbeHaruhiko/items/8b3b11421b431d219617)
* [AndroidでJUnit4とJUnit3.8やEspressoを併用する方法](http://qiita.com/AbeHaruhiko/items/5416120c8a933f0b8147)

## Setup

### 変更点
```groovy:build.gradle
# 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'
```

```java:HogeTest.java
// ~1.1
com.google.android.apps.common.testing.ui.espresso
// 2.0~
android.support.test.espresso
```

### サンプル
```groovy:build.gradle
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'
}
```

[Getting Started](https://code.google.com/p/android-test-kit/wiki/EspressoSetupInstructions)


## AndroidJUnitRunnerについて

ざっくりですが、Espresso 2.0 で導入された [`AndroidJUnitRunner` のオフィシャルWiki](https://code.google.com/p/android-test-kit/wiki/AndroidJUnitRunnerUserGuide)の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では以下のようなコードでした。

```java
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 によりインジェクトされていましたが、手動で行う必要があります。

```java
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
```
* `AndroidJUnitRunner` に認識させるため、全てのテストに `@Test` を付けます。
* `tearDown` をオーバライドし `@After` を付け、 `super.tearDown()` を呼び出します。これはオブジェクトのリークを防ぐために重要です。

`ActivityInstrumentationTestCase2` でJUnit4を使った例です。

```java
@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ベースだったりして）若干古いですが、考え方はいまでも充分役に立ちます。

[JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus) ](http://www.amazon.co.jp/JUnit%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-~%E4%BD%93%E7%B3%BB%E7%9A%84%E3%81%AB%E5%AD%A6%E3%81%B6%E3%83%A6%E3%83%8B%E3%83%83%E3%83%88%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E6%8A%80%E6%B3%95-WEB-PRESS-plus/dp/477415377X)
![JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus) ](http://ecx.images-amazon.com/images/I/51TaOch1LJL._AA160_.jpg)