読者です 読者をやめる 読者になる 読者になる

visible true

技術的なメモを書く

Gradle Plugin 1.1.0-rc1でJVMでテストを実行出来るようになったらしい

New Build System - Android Tools Project Siteの1.1.0-rc1のRelease Noteに以下の文が

Unit testing support. Unit testing code is run on the local JVM, against a special version of android.jar that is compatible with popular mocking frameworks (e.g. Mockito).

という事で早速試してみました。

セットアップ

Android Studioを1.1 beta 4にする

まずはAndroid Studioを1.1 Beta 4以上にします。Android Studioを1.1 Beta 4はcanary channelで配布されてます。

f:id:sys1yagi:20150206152430p:plain

gradle pluginを1.1.0-rc1にする

プロジェクト直下のbuild.gradle

dependencies {
  classpath 'com.android.tools.build:gradle:1.1.0-rc1'
}

dependenciesにtestCompileでjunit4を追加する

gradle plugin 1.1.0-rc1からdependenciesにtestCompileというキーワードが増えました。localのUnit Testで使うライブラリを定義できます。

dependencies {
  testCompile 'junit:junit:4.11'
  testCompile "org.mockito:mockito-core:1.9.5"
}

Enable Unit Testing Supportを有効にする

Android Studioの[Preference]-[Gradle]-[Experimental]でEnable Unit Testing supportを有効にします。この設定の後gradle syncを行うかAndroid Studioを再起動して下さい。

f:id:sys1yagi:20150206152501p:plain

テストを書く

テストはsrc/test/java配下に置きます。ディレクトリを作ってもそのままではコードを認識してくれません。

f:id:sys1yagi:20150206153657p:plain

Build VariantsTest ArtifactUnit Testsに変更すると各種dependenciesのパスが通った状態でコードを記述出来るようになります。

f:id:sys1yagi:20150206153714p:plain

テストコードを書きます。

ListUtils.java

public class ListUtils {
  public static <T> T head(List<T> list) {
    if (list == null || list.isEmpty()) {
      return null;
    }
    return list.get(0);
  }
}

普通のJUnit4です。

import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

public class ListUtilsTest {
  @Test
  public void head() {
    List<String> strings = new ArrayList<>();

    assertThat(ListUtils.head(strings), nullValue());

    strings.add("a");
    assertThat(ListUtils.head(strings), is("a"));

    strings.add("b");
    assertThat(ListUtils.head(strings), is("a"));
  }
}

Gradleで実行する

まずはGradleで実行してみます。gradle pluginを1.1.0-rc1からtest, testDebug, testReleaseなどのタスクが増えました。

./gradlew testDebug

module_name/build/reports/tests/index.htmlにレポートが吐かれます。

f:id:sys1yagi:20150206153733p:plain

Android Studioで実行する

Android StudioではEdit ConfigurationsでJUnitのConfigurationを定義します。デフォルトとの変更点は下部のBefore launchです。Makeになっているのでそれを削除しGradle-awareを選択します。そこでtestDebug等のタスクを指定します。

f:id:sys1yagi:20150206153751p:plain

あとは実行するだけ。エラーになるとreportsのindex.htmlを見に行かないとダメです。まだこの辺はこなれてない感じですね。

f:id:sys1yagi:20150206153815p:plain

まとめ

とりあえずテストをlocalで実行する所まで書きました。今回追加されたUnit Testの機能はAndroidTestCompile共存するのでdeviceが必要なテストと不要なテストを分けて管理出来るようになりました。

Unit Testの方はmockable-android.jarというjarを生成していました。これをテストで参照している様です。中身をザッとみたら実装はなくどれもRuntimeExceptionをthrowしていました。mockableという事でUnit TestではAndroid Frameworkのクラスをmockitoなどでmockして差し替えましょうという事みたいです。

TextUtilsとかもmock差し替えが必要みたいなのでRobolectricとの置き換えはまだ先になりそうです(そもそも置き換えられるかもちょっと不明)。Shadow的な仕組みが今後追加されるんでしょうか?気になる所です。

参考