top of page
Matt

効率的なAndroid UIテスト:依存性注入フレームワークなしの機能的技術

はじめに

私の他のブログ投稿で議論されているように、プロジェクトのための良質でクリーンな自動テストを書く重要性は言い過ぎることはありません。この投稿では、機能的アプローチを使用してAndroidのテストを書く方法を示します。副作用を持つ関数を注入して様々なシナリオを容易にする方法、そして依存性注入(DI)フレームワークを必要とせずにこれを行う方法を説明します。DIフレームワークはしばしば不必要なボイラープレートと複雑さを加えます。


アプリをテスト用に構造化する

関数型プログラミングでは、関数はクラスとは対照的に第一級の構成要素です。アプリを効果的にテストするためには、関数を注入し、アプリのすべての異なる振る舞いをカバーするテストを書くことができるようにする必要があります。例えば、その日のニュースフィードを表示するシンプルなアプリを考えてみましょう。私たちは以下のような振る舞いのテストを書くことができます:

  • ニュースがない場合に親切なメッセージを表示する。

  • ニュースの見出しを正しく表示する。

  • ニュース取得時にエラーがある場合、親切なエラーメッセージを表示する。


このために、Either<Error, Response>を返すgetNewsFという関数を持つことができます。この関数をアプリコードに注入する必要がありますので、テストでは、呼び出された際の関数の振る舞いを制御し、上述のテストを効果的に書くことができます。


ところで、Either型は関数型の型であり、arrow coreから来ています:https://arrow-kt.io/


AppFとAppFProvider:

私たちのアプリは通常、注入したい複数の関数を含んでいます。まず、AppFというクラスを作成しましょう。これは私たちの関数を含むシンプルなデータクラスです:

data class AppF(
    val getNewsF: () -> Either<Error, Response>
)

AppFを注入するためのエントリーポイントは、AppFProviderと呼ばれるシングルトンクラスからAppFインスタンスにアクセスする遅延セッターです:

object AppFProvider {
    var appF: AppF = AppF()
}

そして、これがMainActivityに注入されます:

class MainActivity : ComponentActivity() {
    private val appF: AppF by lazy { AppFProvider.appF }
    ...
}

デフォルトでは、AppFProviderはREALインスタンスで設定されていますが、テストでは必要に応じて任意の実装に変更することができます。アクティベーションを制御するために、テスト内で手動でシナリオを作成する必要があります。テストが終了したら、シナリオを閉じます。以下がその方法です:

fun init(appF: AppF = buildTestAppF()): ActivityScenario<MainActivity> {
    AppFProvider.appF = appF

    return ActivityScenario.launch(MainActivity::class.java)
}

getNewsテストの例:

@Test
fun testIfGettingNewsErrorsThenErrorIsDisplayedAndLogged() {
    val expectedError = Error("Oh dear! failed to get news")
    val loggedErrors = mutableListOf<Error>()
    val logError = { error: Error ->
        loggedErrors.add(error)
        Unit
    }
    init(
        AppF(
            getNewsF = { expectedError.left() }
        )
    ).use {
        loggedErrors.shouldHaveSize(1)
        loggedErrors[0].shouldBe(expectedError)

        onView(withText("Failed to get news. Please try again later"))
            .check(matches(isDisplayed()))
    }
}

サポート方法

このコンテンツは常に無料で提供されますので、価値があると感じたら、他の人と共有することを検討してください。さらに、私たちのゲームをダウンロードして正直なレビューを残すことは、私たちを大いにサポートします。質問やフィードバックがあればお気軽にお問い合わせください。可能な限り迅速に対応いたします。


本日、Apple App StoreからFalling Skyをダウンロードしてください:https://apps.apple.com/app/id6446787964


Xで私たちをフォローしてください:https://x.com/_kingdomarcade

閲覧数:1回
bottom of page