Subscribed unsubscribe Subscribe Subscribe

Islands in the byte stream

Technical notes by id:gfx

Robolectric-InstrumentationでテストをRobolectricとAndroid両方で走らせる

テストクラスを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/testsrc/androidTest にシンボリックリンクする

(cd app/src && ln -s test androidTest)

テストをAndroid Instrumentation Testing API準拠にする

Robolectric-Instrumentationの実体は com.android.support.test:runner の互換実装です。具体的には、 AndroidJUnit4InstrumentationRegistry です。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を起動することくらいならできますが