61
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Robolectric に対応したプロジェクトを作る

Last updated at Posted at 2014-02-12

今更ながら、この記事の通りに、Robolectric に対応したプロジェクトを作る手順をまとめておきます。

Robolectric の役割

Android は、標準のフレームワークにテストフレームワークも含んでいます。
JUnit3 をベースとして、モジュールのテストや画面のテストの為のフレームワークが提供されています。

一方、実行環境の制約から、Android エミュレータや端末上での実行が要求されます。テストの実行のためにエミュレータを立ち上げたり、テストの apk をインストールしたりする必要が有るため、テストそのものの実行に手間と時間がかかってしまいます。

Robolectric では、Android のフレームワークにある各種の API を JVM 上でエミュレートすることにより、テストの実行時間を短くスピーディにすることができます。

手順の概要

  1. build.gradle の設定でテストの準備をする
  2. TestRunner を拡張して、AndroidManifest を見えるようにする
  3. テストを書く

build.gradle の準備

ビルドスクリプトに記述する内容は以下の通りです。

  1. android-test プラグインの導入
  2. robolectric プラグインの導入
  3. JUnit4, Robolectric, Android-FEST への依存の宣言
  4. テスト用のディレクトリの変更

現在、Robolectric は KitKat に対応していないため、TargetSDK と CompileWith の API Level を 18 にしておきます。
この設定は@Configアノテーションを用いてテストコード中で設定できます。

2015/03/10 追記:以下のスクリプトはすでに古く、動作する保証がありません。現時点で最新の記述はこの下にあります。

buildscript {
    // ビルドスクリプトの依存
    repositories {
        mavenCentral()
        maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.8.+'
        classpath 'com.squareup.gradle:gradle-android-test-plugin:0.9.1-SNAPSHOT'
    }
}

repositories {
    mavenCentral()
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

apply plugin: 'android'
apply plugin: 'android-test'

android {
    compileSdkVersion 18
    buildToolsVersion "19.0.1"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 18
        versionCode 1
        versionName "1.0"
    }

    sourceSets {
        instrumentTest.setRoot('src/test')  // テストディレクトリを test に変更する
    }
}

dependencies {
    compile 'com.android.support:gridlayout-v7:19.0.1'
    compile 'com.android.support:support-v4:19.0.1'
    compile 'com.android.support:appcompat-v7:19.0.1'
    testCompile 'junit:junit:4.11' // JUnit 4
    testCompile 'org.robolectric:robolectric:2.3-SNAPSHOT'  // Robolectric 本体
    testCompile 'com.squareup:fest-android:1.0.+' // FEST(Fixtures for Easy Software Testing) を Android で利用するためのライブラリ
    instrumentTestCompile 'junit:junit:4.11'
    instrumentTestCompile 'org.robolectric:robolectric:2.3-SNAPSHOT'
    instrumentTestCompile 'com.squareup:fest-android:1.0.+'
}

2015/03/10 追記:こちらが最新

buildscript {
    // ビルドスクリプトの依存
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.1.0'
        classpath 'org.robolectric:robolectric-gradle-plugin:1.0.1'
    }
}

repositories {
    jcenter()
}

apply plugin: 'com.android.application'
apply plugin: 'org.robolectric' // 少し前まで robolectric でしたが、正式リリース以後 org.robolectric となります

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    // robolectric のテストは androidTest ディレクトリに放り込むので sourceSet について特に記述なし
}

dependencies {
    compile 'com.android.support:gridlayout-v7:19.0.1'
    compile 'com.android.support:support-v4:19.0.1'
    compile 'com.android.support:appcompat-v7:19.0.1'
    // 以下、様々な transitive dependencies を exclude します
    androidTestCompile('junit:junit:4.11') { // JUnit4
        exclude module: 'hamcrest-core'
    }
    androidTestCompile('org.robolectric:robolectric:2.4') { // Robolectric 本体
        exclude module: 'classworlds'
        exclude module: 'commons-logging'
        exclude module: 'httpclient'
        exclude module: 'maven-artifact'
        exclude module: 'maven-artifact-manager'
        exclude module: 'maven-error-diagnostics'
        exclude module: 'maven-model'
        exclude module: 'maven-plugin-registry'
        exclude module: 'maven-profile'
        exclude module: 'maven-project'
        exclude module: 'maven-settings'
        exclude module: 'nekohtml'
        exclude module: 'plexus-container-default'
        exclude module: 'plexus-interpolation'
        exclude module: 'plexus-utils'
        exclude module: 'wagon-file'
        exclude module: 'wagon-http-lightweight'
        exclude module: 'wagon-http-shared'
        exclude module: 'wagon-provider-api'
        exclude group: 'com.android.support', module: 'support-v4'
    }
    androidTestCompile 'org.mockito:mockito-all:1.9.5'
    androidTestCompile 'com.squareup:fest-android:1.0.+' // FEST(Fixtures for Easy Software Testing) を Android で利用するためのライブラリ
}

TestRunner の準備

src/test/javaにテストを配置する関係で、Robolectric が AndroidManifest を見つけられなくなるため、TestRunner を拡張して場所を指定します。

2015/03/10 追記:以下の TestRunner は必要無くなりました。org.robolectric.RobolectricTestRunner を使用します。AndroidManifest については、@Configアノテーションを用います。

import org.junit.runners.model.InitializationError;
import org.robolectric.AndroidManifest;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.res.Fs;

public class RobolectricGradleTestRunner extends RobolectricTestRunner {
    public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override
    protected AndroidManifest getAppManifest(Config config) {
        String manifestProperty = System.getProperty("android.manifest");
        if (config.manifest().equals(Config.DEFAULT) && manifestProperty != null) {
            String resProperty = System.getProperty("android.resources");
            String assetsProperty = System.getProperty("android.assets");
            return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty),
                    Fs.fileFromPath(assetsProperty));
        }
        AndroidManifest appManifest = super.getAppManifest(config);
        return appManifest;
    }

}

以上で、プロジェクトの準備は完了です。

テストの記述

Android フレームワークが提供するテストスートと違い、JUnit4 が使えるので、以下のようにテストが記述できます。

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import static org.junit.Assert.assertTrue;

@RunWith(RobolectricTestRunner.class) // TestRunner の指定
@Config(manifest = "src/main/AndroidManifest.xml", emulateSdk = 18) // sdk の api level を指定する
public class MyModuleTest {
    @Test // テストケースの表明
    public void shouldPass() throws Exception {
        assertTrue(true);
    }
}

テストの実行は以下のようにします。

$ ./gradlew test

これで、エミュレータ無しにテストが実行できるようになりました。

61
61
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
61
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?