テストクラスをAndroid Instrumentation TestsとRobolectric Tests両方で走らせる - Islands in the byte stream のハックをライブラリ化しました。
gfx/RobolectricInstrumentation · GitHub
Ormaのほうはこれに書き換え済みです。
これはRobolectricでAndroid InstrumentationのAPIのサブセットを実装することにより、同じテストコードを両方のテストフレームワークで走らせられるようにするものです。なおEspressoを使うテストは移植できません*1。
新規での導入手順は以下のとおりです。 example projectが完成形です。
Robolectric Instrumentationを導入する
dependenciesに書くだけです。他にも必要なライブラリがあれば書いてください。
dependencies { testCompile 'com.github.gfx.android.robolectricinstrumentation:robolectric-instrumentation:3.0.2' testCompile 'org.robolectric:robolectric:3.0' testCompile 'junit:junit:4.12' }
robolectric.propertiesを導入する
サブプロジェクトで app
があるとすれば、 app/src/test/resources/roblectric.properties
に設定ファイルを置きます。これはRobolectric全体の設定に使うファイルで、テストクラスではRobolectric APIを使えないのでこの設定ファイルを使う必要があります。またRobolectric-Instrumentation でも project
という設定が追加で必要です。
最低限必要な設定は以下のとおりです。
# サブプロジェクトの名前 project=app # RobolectricでシミュレートするAPI level sdk=16
strings.xmlなどのリソースにアクセスしたいときは更に BuildConfig
の設定をする必要があります。
constants=com.example.app.BuildConfig
src/test
を src/androidTest
にシンボリックリンクする
(cd app/src && ln -s test androidTest)
テストをAndroid Instrumentation Testing API準拠にする
Robolectric-Instrumentationの実体は com.android.support.test:runner
の互換実装です。具体的には、 AndroidJUnit4
と InstrumentationRegistry
です。Robolectric APIではなくこれらを使うように書き換えます。
+ @RunWith(AndroidJUnit4.class) - @RunWith(RobolectricGradleTestRunner.class) - @Config(constants = BuildConfig.class, sdk = 16)
+ Context context = InstrumentationRegistry.getContext(); - Context context = RuntimeEnvironment.application;
これで、 ./gradlew test
と ./gradlew androidTest
両方で動くようになるはずです。
ただEspressoなどviewを含めたテストはできませんし、Handlerまわりを使っていると動かないなどのRobolectric特有の現象を考慮する必要があります。Ormaでは特に問題なく移植できましたが、これはほとんどSQLite関連のAPIしか使っていないからです。
*1:InstrumentationRegistry経由でActivityを起動することくらいならできますが