42
44

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.

Android Studio&Robolectricでテストを正しく&高速に動かす

Last updated at Posted at 2015-06-16

TL;DR

Android Studioでテストをエラーなく、かつ高速に実行できるようになるまでの手順があまりに多いので、最新の手順をまとめてみた。

テストコードの準備、またはRobolectricの導入

app/bulid.gradleに依存関係を追加

dependencies {
    ...
    testCompile 'org.robolectric:robolectric:2.4'
}

最新版を公式で確認して下さい。

CustomRobolectricTestRunnerを設置

public class CustomRobolectricTestRunner extends RobolectricTestRunner {
    public CustomRobolectricTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
        String buildVariant = (BuildConfig.FLAVOR.isEmpty() ? "" : BuildConfig.FLAVOR + "/") + BuildConfig.BUILD_TYPE;
        System.setProperty("android.package", BuildConfig.APPLICATION_ID);
        System.setProperty("android.manifest", "build/intermediates/manifests/full/" + buildVariant + "/AndroidManifest.xml");
        System.setProperty("android.resources", "build/intermediates/res/" + buildVariant);
        System.setProperty("android.assets", "build/intermediates/assets/" + buildVariant);
    }
}

(※Resource not foundなどというエラー出たら補足を参照のこと)

Robolectricを参照するテストコードにannotationを追加

@Config(emulateSdk = 18)
@RunWith(CustomRobolectricTestRunner.class)
public class FoobarTest {
    @Test
    public testHoge() {
        Context context = Robolectric.applciation.getApplicationContext();
        Foobar foobar = new Foobar(context);
        ...
    }
}

Android Studioの設定

Run ConfigurationsでJUnit用のWorking Directoryを $MODULE_DIR$ に変更

追記:1.2.2のデフォルト設定では$MODULE_DIR$になっています。

image

image

defaultを変更しておくと便利です。既存のConfigurationがある場合は書き換えるか消しておくとよいと思います。

Build VariantsのタブでTest ArtifactをUnit Testsに変更

image

デフォはAndroid Instrumentation Testsになってるはずです。

実行

image

全部実行はtest/javaディレクトリを右クリックすれば簡単にできます。1回実行すればRun Configurationsに追加されます。

テストの開始までが遅い場合

Run/Debug ConfigurationsのBefore launchで"Gradle-aware Make"のほかに"Make"とかの余計なものがないか確認します。

image

追記:1.2.2のデフォルト設定では、Makeだけが入ってました。下記の設定をしなければ、Makeにしておくほうがデフォルトに準拠していて良いかもです。

また、Android Studio 1.4未満はテスト実行に不要なapk作成までやってしまい遅いので、Gradle-aware Makeにtaskの設定をするともう少し早くなります。

gradle-aware-make.png

FooBarの部分は"Debug"など、 現在の Build Variantに該当する名前を書きます。

補足

Robolectric

Androidの機能を使うテストは本来は実機やエミュレータで実行しなくてはなりませんが、このライブラリを使うとPC上で高速に実行できるようになります。

CustomRobolectricTestRunner

元ネタ:https://github.com/robolectric/robolectric-gradle-plugin/issues/142#issuecomment-103962546

なぜ必要か

RobolectricのJavaライブラリに、buildされたresource群やAndroidManifestファイルの位置を知らせるために必要です。
これがないとgetResources()やgetString()を叩くなどするとresourceが見つからない旨のエラーが出ます。

別の対応としてrobolectric-gradle-pluginもありますが、Android StudioでJUnit実行するとgradleを介さず起動するので、効果がありません。なので、pluginでやってることをCustomRobolectricTestRunnerにやらせます。
(余談ですが最近のrobolectric-gradle-pluginRobolectricGradleTestRunnerが不要になったようです。)

Resource not foundのようなエラーが出る場合

build.gradleでapplicationIdを使い分けている等の場合は、android.packageのBuildConfig.APPLICATION_IDをデフォルトのapplicationId(恐らくAndroidManifest.xmlのandroid:package)に書き換えないとエラーが出ます。
直接パッケージ名を記載したくない場合はbuild.gradleにbuildConfigFieldを書くと便利です。
https://github.com/robolectric/robolectric-gradle-plugin/issues/142#issuecomment-112386932

@Config

robolectric 3.0ならemulateSdkは21までいけるらしいです。書き方が@Config(sdk = 21)に変わっています。
robolectric 3.0ならapp/src/test/resources/robolectric.propertiessdk=21と記載すれば@Config書かなくてすみます。( @kyanro@github さんありがとうございます!)

$MODULE_DIR$

gradleは最初からmoduleの中(/path/to/project/app)で実行してくれるんですが、Android StudioのJUnit実行のデフォルトはprojectディレクトリ(/path/to/project)になってます。

Before launchのGradle-aware MakeとMake

手元の環境だとなぜだか実行時に2回ビルドが走るのでおかしいなと思ったら、MakeとGradle-aware Makeの両方が入っていました。 もしかしたら自分でやったのかもしれない・・・。 @ainame も同じ設定になっていたらしいので、前のバージョンからのアップデートとかでなるのかもしれないです。

42
44
2

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
42
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?