Android Studio 1.5 で JUnit4 を使い始める


# この文章の目的
Android開発でJUnitを導入する際の、手順の提示。

# この文章でできるようになること
Android Studio 1.5 で JUnit4 を使い始められるようになる。
特に、実機・エミュレータを使用 *しない* JUnitでのテストを使えることを知る。

# この文章で身につかないこと
* Android Studioのインストール方法
* Android Studioの使い方
* JUnitの良い記述方法
* モックを利用したJUnitによるテスト記述方法
* UnitTestの良い作り方
* UnitTestにおけるテスト手法

# 手順
本家の"Getting Started with Testing"を読んでおくと、流れは掴める。

## 参考
* [Getting Started with Testing](http://developer.android.com/intl/ja/training/testing/start/index.html)
* [Android Testing Support Library](https://google.github.io/android-testing-support-library/)

## プロジェクト作成
今回は、新規で作成する。
![プロジェクト作成](https://qiita-image-store.s3.amazonaws.com/0/10784/2dbb0c32-3efb-f1aa-c84c-9a9ef983d544.png "プロジェクト作成")

`Application Name`は`NewSampleUnitTestApp`としておく。
`Company Domain`は各自で定義する。
![プロジェクト作成](https://qiita-image-store.s3.amazonaws.com/0/10784/7dbeeb63-1630-1ce0-b78b-0faec134bb10.png "プロジェクト作成")

`Phone and Tablet`を選択。
![プロジェクト作成](https://qiita-image-store.s3.amazonaws.com/0/10784/0f60f44b-2f8b-3be8-5563-ac8f3bfd57b0.png "プロジェクト作成")

`Blank Activity`を選択。
![プロジェクト作成](https://qiita-image-store.s3.amazonaws.com/0/10784/53485b84-6f3b-0247-c7de-c3c1643b8b8a.png "プロジェクト作成")

`Finish`を選択。
![プロジェクト作成](https://qiita-image-store.s3.amazonaws.com/0/10784/94329d6f-5e79-b082-d7c7-105794b70c20.png "プロジェクト作成")

## JUnitを使えるようにする
使用するライブラリの組み込み。
メニューの`Project Structure`経由に該当する編集領域はあるが、モジュールの検索で一部のものがひっかからないようので、直接編集した方が良い。

まずは、プロジェクトのトップにある`build.gradle`を確認。
![build.gradle編集](https://qiita-image-store.s3.amazonaws.com/0/10784/97efe3ea-b943-4af0-1943-544d35c6d3d2.png "build.gradle編集")

参考の`Getting Started with Testing`にある`Configure Your Project for Local Unit Tests`に書かれているように`JUnit`のライブラリの組み込み。
記載された内容のうち、最低限必要なものを追加する。

必要なライブラリの指定として、三つを追加する。
`com.android.support:support-annotations`のバージョンは、他のライブラリに合わせたものに変更。
同様に、`com.android.support.test:runner`と`com.android.support.test:rules`のバージョンは、下記サイトに合わせて変更。
https://google.github.io/android-testing-support-library/downloads/index.html

また、テストランナーの指定も追加。

```NewSampleUnitTestApp/app/build.gradle
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "net.tacck.app.android.newsampleunittestapp"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" // テストランナーの指定
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:design:23.2.1'

    androidTestCompile 'com.android.support:support-annotations:23.2.1' // ライブラリ追加
    androidTestCompile 'com.android.support.test:runner:0.5' // ライブラリ追加
    androidTestCompile 'com.android.support.test:rules:0.5' // ライブラリ追加
}
```

Android Studioの画面にメッセージが出るので「Sync Now」をクリックする。
しばらく待って、エラーメッセージが出なければOK。


## ローカル実行のテスト
### テスト対象クラスの作成
左列にある`Build Variants`を選択し、`Test Artifact`に`Unit Tests`を選択する。
![テスト対象クラスの作成"](https://qiita-image-store.s3.amazonaws.com/0/10784/b2df9704-d8c6-f0eb-14a4-974bc1f40513.png "テスト対象クラスの作成"")


"Android"から"Project"へ変更し、`app/src/main/java/[Package名]`の下に`SampleModel`クラスを作成する。

![テスト対象クラスの作成"](https://qiita-image-store.s3.amazonaws.com/0/10784/3ca2ef2b-fa03-8c71-86b2-fefd960a9e97.png "テスト対象クラスの作成"")


![テスト対象クラスの作成](https://qiita-image-store.s3.amazonaws.com/0/10784/d45184d2-6a65-88c7-0907-6b0e2c7b79f0.png "テスト対象クラスの作成")

作成したら、下記のように`getTrue()`メソッドを追加する。

```SampleModel.java
package net.tacck.app.android.newsampleunittestapp;

public class SampleModel {

    public boolean getTrue() {
        return true;
    }
}
```

### テスト作成
`SampleModel.java`ファイルのクラス名`SampleModel`へカーソルを合わせ、`Option + Enter`とする。
メニューの`Crate Test`を選択する。
ダイアログが出たらJUnit4を指定し、作成した`getTrue()`を選択する。
生成されたテストクラスのメソッド`testGetTrue()`にテストコードを記述する。
![テスト作成](https://qiita-image-store.s3.amazonaws.com/0/10784/5abf3e13-30be-428d-644d-95c93ddcb8c4.png "テスト作成")
![テスト作成](https://qiita-image-store.s3.amazonaws.com/0/10784/0f97579b-fdd1-3824-690d-bab9c8e76d07.png "テスト作成")

ファイルが生成されたら、下記のようにテストコードを記述する。

```SampleModelTest.java
package net.tacck.app.android.newsampleunittestapp;

import org.junit.Test;
import static org.junit.Assert.*;

public class SampleModelTest {

    @Test
    public void testGetTrue() throws Exception {
        SampleModel sampleModel = new SampleModel();
        assertTrue(sampleModel.getTrue());
    }
}
```

### 実行
Project内の`SamleModelTest.java`ファイル上で右クリックし、`Run 'SampleModelTest'`を選択する。
![実行](https://qiita-image-store.s3.amazonaws.com/0/10784/d93a052f-6d35-f232-cd49-77bf873bfdc2.png "実行")

下側にテスト結果が表示される。今回は`All Tests Passed`となっており、作成したテストが成功になっている。
![実行](https://qiita-image-store.s3.amazonaws.com/0/10784/a705406b-8cd0-ddcb-a1b6-cd596f51d94c.png "実行")

### カバレッジ確認
同様にProject内の`SamleModelTest.java`ファイル上で右クリックし、`Run 'SampleModelTest' with Coverage`を選択する。

下側に結果、右側にカバレッジの状況が表示される。`Element`にあるパッケージ名をダブルクリックすると、各クラスごとのカバレッジが表示される。
![カバレッジ確認](https://qiita-image-store.s3.amazonaws.com/0/10784/d574ffb3-6d30-f503-d06f-c997f7db8d3f.png "カバレッジ確認")


## エミューレータ・実機実行のテスト
### テスト対象クラス・メソッドの作成
左列にある`Build Variants`の`Test Artifact`にて、`Android Instrumentation Tests`を選択する。

`app/src/main/java/[Package名]`の下にある既存の`MainActivity.java`に、下記のように新規メソッドとして`getFalse ()`を追加する。

```MainActivity.java
package net.tacck.app.android.newsampleunittestapp;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public boolean getFalse() {
        return false;
    }
}
```

### テスト作成
`MainActivity.java`ファイルのクラス名`MainActivity`へカーソルを合わせ、`Option + Enter`とする。
メニューの`Crate Test`を選択する。
ダイアログが出たらJUnit4を指定し、作成した`getFalse()`を選択する。
生成されたテストクラスのメソッド`testGetFalse()`にテストコードを記述する。
![テスト作成](https://qiita-image-store.s3.amazonaws.com/0/10784/df1392d6-ce30-54d1-f364-82c0263bf3e3.png "テスト作成")
![テスト作成](https://qiita-image-store.s3.amazonaws.com/0/10784/5fdd89f8-7cd8-7f06-836a-a6d7d8c7f5a3.png "テスト作成")

ダイアログでファイルの作成先を尋ねられるので、`app/src/androidTest/java/[パッケージ名]`となるものを選択する。
![スクリーンショット 2016-04-10 21.55.15.png](https://qiita-image-store.s3.amazonaws.com/0/10784/f4beb35a-4363-92e6-5fe2-5540dd477e82.png "スクリーンショット 2016-04-10 21.55.15.png")

生成されたテストクラスのメソッド`testGetFalse()`にテストコードを記述する。
この時、元のActivityを参照するために、`@Rule`アノテーションを利用して`ActivityTestRule`も作成する。

```MainActivityTest.java
package net.tacck.app.android.newsampleunittestapp;

import android.support.test.rule.ActivityTestRule;

import org.junit.Rule;
import org.junit.Test;

import static org.junit.Assert.*;

public class MainActivityTest {

    @Rule
    public  ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void testGetFalse() throws Exception {
        assertEquals(false, mActivityRule.getActivity().getFalse());
    }
}
```

### 実行
Project内の`MainActivityTest.java `ファイル上で右クリックし、`Run 'MainActivityTest'`を選択する。
![実行](https://qiita-image-store.s3.amazonaws.com/0/10784/df9aa870-2b5c-387a-c59a-5681c78e5fe4.png "実行")

エミュレータが起動されていない・実機が接続されていない場合は、エミュレータ起動選択画面が出る。
![スクリーンショット 2016-04-10 22.16.21.png](https://qiita-image-store.s3.amazonaws.com/0/10784/312da8c9-8975-23d2-24f8-d1b5791734a9.png "スクリーンショット 2016-04-10 22.16.21.png")

実機接続・エミュレータ起動ができて正しく実行できる状態となったら、テストが実行され下側にテスト結果が表示される。今回はパッケージ名の右側が`P:1`となっており、作成したテストが成功になっている。
![実行](https://qiita-image-store.s3.amazonaws.com/0/10784/ecb416d3-627a-00aa-c394-7e09e747badb.png "実行")