コンテンツ プロバイダのテスト

データの保存および取得、または他のアプリからのデータへのアクセスを可能とするためにコンテンツ プロバイダを実装する場合は、プロバイダをテストして、予期せぬ動作が生じないことを確認する必要があります。このレッスンでは、コンテンツを公開するプロバイダをテストする方法について説明します。このテスト方法は、コンテンツをアプリにだけ限定するプロバイダにも適用できます。

コンテンツ プロバイダの説明もご覧ください。

コンテンツ プロバイダの統合テストを作成する

Android では、アプリがコンテンツ プロバイダを参照する場合、コンテンツ プロバイダはデータのテーブルを提供するデータ API とみなされます(ただし、その内部はビューには非表示になっています)。コンテンツ プロバイダには多くのパブリック定数がありますが、一般的にパブリック メソッドはあったとしてもごくわずかで、パブリック変数はありません。したがって、プロバイダのパブリック メンバーのみに基づいてテストを作成する必要があります。このように設計されたコンテンツ プロバイダは、プロバイダ自身とユーザーとの間のコントラクトを提供します。

コンテンツ プロバイダを使用すると実際のユーザーデータにアクセスできるため、必ず隔離されたテスト環境でコンテンツ プロバイダをテストすることが重要です。このアプローチでは、テストケースで明示的に設定されたデータ依存関係に対してのみアプリを実行できます。つまり、テストでは実際のユーザーデータを変更しません。たとえば、前のテストのデータが残っていたことが原因で失敗するようなテストを作成してはなりません。同様に、テストで実際の連絡先情報をプロバイダに追加または削除することは避けるべきです。

コンテンツ プロバイダを隔離された状態でテストするには、ProviderTestCase2 クラスを使用します。このクラスを使用すると、IsolatedContextMockContentResolver などの Android モック オブジェクト クラスを使用して、実際のユーザーデータに影響を与えることなくファイルとデータベースの情報にアクセスできます。

統合テストは、JUnit 4 テストクラスとして作成する必要があります。JUnit 4 テストクラスの作成方法と JUnit 4 アサーションの使用方法の詳細については、ローカル単体テストクラスを作成するをご覧ください。

コンテンツ プロバイダの統合テストを作成するには、次の手順を実施する必要があります。

  • テストクラスを ProviderTestCase2 のサブクラスとして作成します。
  • テストクラス定義の先頭に @RunWith(AndroidJUnit4::class) アノテーションを追加します。
  • AndroidX Test がデフォルトのテストランナーとして提供する AndroidJUnitRunner クラスを指定します。この手順の詳細については、テストのスタートガイドをご覧ください。
  • ApplicationProvider クラスから Context オブジェクトを設定します。次のスニペットの例をご覧ください。

    Kotlin

        @Throws(Exception::class)
        override fun setUp() {
            super.setUp()
            context = ApplicationProvider.getApplicationContext<Context>()
        }
        

    Java

        @Override
        protected void setUp() throws Exception {
            super.setUp();
            setContext(ApplicationProvider.getApplicationContext());
        }
        

ProviderTestCase2 の仕組み

ProviderTestCase2 のサブクラスでプロバイダをテストします。この基本クラスは AndroidTestCase を拡張するもので、JUnit テスト フレームワークと、アプリの権限をテストするための Android 固有のメソッドが提供されます。このクラスの最も重要な機能は初期化であり、それによって隔離されたテスト環境を作成します。

初期化は、サブクラスが固有のコンストラクタで呼び出す、ProviderTestCase2 用のコンストラクタで行われます。ProviderTestCase2 コンストラクタは、ファイルとデータベースのオペレーションを可能にする IsolatedContext オブジェクトを作成しますが、Android システムとのその他のインタラクションをスタブ化します。ファイルとデータベースのオペレーション自体は、デバイスまたはエミュレータに対してローカルで特別なプレフィックスを持つディレクトリで行われます。

コンストラクタは、テスト用のリゾルバとして使用する MockContentResolver を作成します。

最後に、コンストラクタはテスト対象のプロバイダのインスタンスを作成します。これは通常の ContentProvider オブジェクトですが、すべての環境情報を IsolatedContext から取得するので、隔離されたテスト環境での処理のみに制限されます。テストケース クラスで行われるすべてのテストは、この隔離されたオブジェクトに対して実行されます。

コンテンツ プロバイダの統合テストは、インストゥルメント化単体テストと同じ方法で実行します。コンテンツ プロバイダの統合テストを実行するには、インストゥルメント化単体テストを実行するで説明している手順に従ってください。

テスト項目

コンテンツ プロバイダのテストに固有のガイドラインを次に示します。

  • リゾルバ メソッドでテストする: プロバイダ オブジェクトは ProviderTestCase2 でインスタンス化できますが、必ず適切な URI を使用してリゾルバ オブジェクトでテストする必要があります。そうすることで、通常のアプリが使用するのと同じインタラクションを実行してプロバイダをテストしていることが保証されます。
  • 公開プロバイダをコントラクトとしてテストする: プロバイダを公開して他のアプリで利用できるようにしたい場合は、コントラクトとしてテストする必要があります。その方法の例を次に示します。
    • プロバイダが一般公開している定数でテストします。たとえば、プロバイダのいずれかのデータテーブルの列名を参照する定数を探します。それは必ず、プロバイダによってパブリックに定義された定数でなければなりません。
    • プロバイダが提供するすべての URI をテストします。プロバイダは、同じデータでもそれぞれ異なる側面を参照する複数の URI を提供する場合があります。
    • 無効な URI をテストする: 単体テストでは、意図的に無効な URI でプロバイダを呼び出して、エラーを見つける必要があります。プロバイダの設計が適切であれば、無効な URI に対して IllegalArgumentException がスローされます。
  • 標準的なプロバイダ インタラクションをテストする: ほとんどのプロバイダは、query()insert()delete()update()getType()onCreate() の 6 つのアクセス メソッドを提供します。これらのメソッドがすべて機能することをテストで検証する必要があります。これらのメソッドの詳細については、コンテンツ プロバイダのトピックに説明があります。
  • ビジネス ロジックをテストする: コンテンツ プロバイダがビジネス ロジックを実装している場合は、それをテストする必要があります。ビジネス ロジックには、無効な値の処理、財務計算や算術計算、重複の除去または結合などがあります。