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で配布されてます。
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を再起動して下さい。
テストを書く
テストはsrc/test/java
配下に置きます。ディレクトリを作ってもそのままではコードを認識してくれません。
Build Variants
のTest Artifact
をUnit Tests
に変更すると各種dependenciesのパスが通った状態でコードを記述出来るようになります。
テストコードを書きます。
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
にレポートが吐かれます。
Android Studioで実行する
Android StudioではEdit ConfigurationsでJUnitのConfigurationを定義します。デフォルトとの変更点は下部のBefore launch
です。Make
になっているのでそれを削除しGradle-aware
を選択します。そこでtestDebug等のタスクを指定します。
あとは実行するだけ。エラーになるとreportsのindex.htmlを見に行かないとダメです。まだこの辺はこなれてない感じですね。
まとめ
とりあえずテストをlocalで実行する所まで書きました。今回追加されたUnit Testの機能はAndroidTestCompile
と共存するのでdeviceが必要なテストと不要なテストを分けて管理出来るようになりました。
Unit Testの方はmockable-android.jar
というjarを生成していました。これをテストで参照している様です。中身をザッとみたら実装はなくどれもRuntimeExceptionをthrowしていました。mockableという事でUnit TestではAndroid Frameworkのクラスをmockitoなどでmockして差し替えましょうという事みたいです。
TextUtilsとかもmock差し替えが必要みたいなのでRobolectricとの置き換えはまだ先になりそうです(そもそも置き換えられるかもちょっと不明)。Shadow的な仕組みが今後追加されるんでしょうか?気になる所です。