0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

男坂Advent Calendar 2020

Day 23

AndroidのUIテストで、非同期処理が完了するまで待機する(Rx編)

Last updated at Posted at 2020-12-22

アプリのE2Eテストするとき、通信が完了するまで待つ必要がある。たとえば、E2Eテストにログイン操作があるとき。通信を待たないとログインの通信中にログイン後の画面を検証したり操作したりするので、当然テストは失敗する。

通信などの非同期処理をRxで実行しているとき、テストを待機させる方法を記述する。Androidアプリ、Espressoで使っているときの話。

実現手順

基本的な考え方

  • IdlingResourceを使う
  • プロダクトコード内のRxの非同期処理1つ1つにIdlingResourceを使った処理は仕込まない

RxJavaPlugins#setScheduleHandlerを使うと実現できる。Rxの全非同期処理の実行前後に、独自の処理を仕込めるので、それを利用する。

Step0. IdlingResourceの導入

大体Espresso入れるときに、セットで導入しているとは思うが、一応示しておく。

app/build.gradle
dependencies {
    // ここではプロダクトコードでIdlingResourceを使わないので、androidTestImplementation
    androidTestImplementation "androidx.test.espresso:espresso-idling-resource:3.3.0"
}

Step1. CountingIdlingResourceで実行中の非同期処理をカウントする

汎用性のある処理なのでJUnitのTestRuleとして実装する。

RxTestRule
class RxTestRule : TestRule {
    override fun apply(base: Statement?, description: Description?): Statement = object : Statement() {
        override fun evaluate() {
            val rxIdlingResource = CountingIdlingResource("RxJava2", true)

            RxJavaPlugins.setScheduleHandler { oldAction ->
                Runnable {
                    try {
                        rxIdlingResource.increment() // 非同期処理が開始前にカウントアップ
                        oldAction.run()
                    } finally {
                        rxIdlingResource.decrement() // 非同期処理が開始前にカウントダウン
                    }
                }
            }

            val registry = IdlingRegistry.getInstance()
            registry.register(rxIdlingResource) // EspressoにCountingIdlingResourceを監視させる

            try {
                base?.evaluate()
            } finally {
                registry.unregister(rxIdlingResource) // テスト終わったらCountingIdlingResourceの監視を解除する
            }
        }
    }

}

※evaluateの中で@Before, @Test, @Afterの処理が実行される。

Step2. Rxの非同期処理の実行数が1以上の間、EspressoのAPIが待機するようにする

先程作ったTestRuleをUIテストを実行するクラスに適用する。

@LargeTest
@RunWith(AndroidJUnit4::class)
class FooTests {
    @get:Rule
    val rxTestRule = RxTestRule()
    ...
}

これで少なくともRxの非同期処理の実行数が1以上の間は、sleepなしでEspressoのAPIが待機してくれるようになる。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?