eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

AndroidでWrite Once Test Anywhereは成功しなかった

経緯

  • JetpackにRobolectricが統合されたことにより、 @RunWith(AndroidJUnit4::class)JUnit Runnerが統一された
  • うまいこと実行できれば、CIで検証しやすくなる(Instrumentation TestをCIでやるのは金か手間か実行時間が必要)

駄目だった箇所

  • こういうExtensionを作って試した

github.com

// build.gradle
android {
    sourceSets {
        androidTest.java.srcDirs += ["src/test/java"]
    }
}
@RunWith(AndroidJUnit4::class)
class HogeTest {

    @Test
    fun fugaTestCase() = compatibleTest {
        // 両方で実行
    }

    @Test
    fun barTestCase() = instrumentationTest {
        // 実機で実行
    }
}
  • 結論から言えば、うまくいかなかった
  • 実行コード内でCoroutineがUI Dispatcherで withTimeout() していると、すぐさまタイムアウト扱いになる
    • コードを追っかけたら、Kotlin Coroutines内部でpostDelayedしているが、Robolectricは瞬時に実行するので待ち合わせがうまくいかない
  • 丁寧に InstrumentationとLocalの両実行 Instrumentationだけで実行 をうまく選択すればまあなんとか、という感じ

Android Studioの対応が不完全だった

  • androidTestのsourceSetsに加えられたソースコードは、実行時に必ずInstrumentationTestが対象となる
    • Run用のConfigurationを自分で書けばもちろん実行できるけど
    • 毎度それを書くのは面倒

今後どうするか?

  • とりあえず実行可能箇所が増えるのは嬉しいので、しばらく両実行のコードを増やすようにしてみる