Android アプリのテストの基礎

このページでは、Android アプリのテストにおける基本方針について説明します。主な内容は次のとおりです。 そのメリットについて説明します。

テストのメリット

アプリの開発において、テストは非常に重要なプロセスです。テストの実行 継続的に確認することで、アプリの正確性、機能性を 動作、ユーザビリティを考慮する必要があります。

アプリを操作して手動でテストできます。用途 エミュレータを使用してシステム言語を変更し、 すべてのユーザーエラーや すべてのユーザーフローを走査します

ただし、手動テストは拡張性が低く、見落とされがちです 改善できます。自動テストでは、 テストを自動的に実行できます。高速かつ反復可能で、一般的に 開発の早い段階で、アプリに関する実用的なフィードバックを得られる プロセスです

Android でのテストの種類

モバイルアプリは複雑で、多くの環境で適切に動作する必要があります。として テストにはさまざまな種類があります。

対象

たとえば、subject に応じて異なる種類のテストがあります。

  • 機能テスト: アプリが想定どおりに動作するか?
  • パフォーマンス テスト: 迅速かつ効率的に実施できるか。
  • ユーザー補助機能のテスト: ユーザー補助サービスとうまく連携するか
  • 互換性テスト: すべてのデバイスと API レベルで適切に動作しますか?

範囲

テストは、サイズ分離度によっても異なります。

  • 単体テストや小規模テストは、アプリのごく一部しか検証しません。 たとえばメソッドやクラスなどです
  • エンドツーエンド テストまたは大規模テスト: 同時に行うことができます。
  • 中程度のテストが中間にあり、2 つのテスト間の統合を確認する 単位を増やす
で確認できます。 <ph type="x-smartling-placeholder">
</ph> テストは、小規模、中規模、大規模のいずれかにできます。
図 1: 一般的なアプリケーションでのテストスコープ。

テストを分類する方法は数多くあります。ただし、最も重要な違いは、 テストが実行される場所です。

インストルメンテーション テストとローカルテスト

テストは Android デバイスまたは別のパソコンで実行できます。

  • インストルメンテーション テストは、物理デバイスまたはエミュレートされた Android デバイスで実行します。 アプリは、コマンドを挿入するテストアプリとともにビルドされ、インストールされます。 状態を読み取ります。インストルメンテーション テストは、通常は UI テスト、アプリの起動、 操作できます。
  • ローカルテストは開発マシンまたはサーバー上で実行されるため、 ホスト側のテストとも呼ばれます。通常は小型で高速であり テスト対象をアプリの他の部分から分離します。
で確認できます。 <ph type="x-smartling-placeholder">
</ph> テストは、デバイス上でインストルメンテーション テストとして実行することも、開発マシン上でローカルテストとして実行することもできます。
図 2: 実行場所に応じたさまざまなタイプのテスト

すべての単体テストがローカルであるわけではなく、すべてのエンドツーエンド テストがデバイス上で実行されるわけでもありません。次に例を示します。

  • 大規模なローカルテスト: ローカルで実行される Android シミュレータを使用できます。 Robolectric として提供されています。
  • 小規模なインストルメンテーション テスト: フレームワーク機能を実装する必要があります。このテストは 複数のデバイスで、複数のバージョンの SQLite との統合を確認する

次のスニペットは、Google Chat で UI を操作する方法を示しています。 インストルメンテーション UI テスト: 要素をクリックして、 表示されます。

Espresso

// When the Continue button is clicked
onView(withText("Continue"))
    .perform(click())

// Then the Welcome screen is displayed
onView(withText("Welcome"))
    .check(matches(isDisplayed()))

Compose UI

// When the Continue button is clicked
composeTestRule.onNodeWithText("Continue").performClick()

// Then the Welcome screen is displayed
composeTestRule.onNodeWithText("Welcome").assertIsDisplayed()

次のスニペットは、ViewModel(ローカル、ホスト側)の単体テストの一部を示しています。 test):

// Given an instance of MyViewModel
val viewModel = MyViewModel(myFakeDataRepository)

// When data is loaded
viewModel.loadData()

// Then it should be exposing data
assertTrue(viewModel.data != null)

テスト戦略の策定

理想としては、あらゆるデバイスでアプリのすべてのコード行をテストするのが理想的です。 確認する必要があります残念ながらこのアプローチは時間がかかりすぎて 費用がかかります

優れたテスト戦略では、テストの忠実度とテストの忠実度の間で適切なバランスを見 テスト、スピード、信頼性ですテスト環境と テストの忠実度は実際のデバイスによって決まります。忠実度の高いテストを実行する エミュレートされたデバイス、または物理デバイス自体が接続されます。忠実度の低いテストが実行される可能性がある ローカル ワークステーションの JVM 上で実行します。高忠実度テストは一般的に時間がかかり、 多くのリソースが必要になるため、すべてのテストを忠実度の高いテストであってはいけません。

不安定なテスト

エラーは、適切に設計、実装されたテスト実行でも発生します。たとえば 実機でテストを実行した場合、 発生し そのテストが失敗する原因になりますコード内の軽微な競合状態では、 ごくわずかな割合で発生しますテストの正解率を 100% に満たさないテスト 時刻が不安定になる。

テスト可能なアーキテクチャ

テスト可能なアプリ アーキテクチャでは、コードを さまざまな部分を 個別に簡単にテストできますテスト可能なアーキテクチャには 利点は、たとえば、可読性、保守性、スケーラビリティに優れ、 可能です。

テスト不可能なアーキテクチャの場合、次のようになります。

  • 規模が大きく、速度が遅く、不安定なテスト。単体テストができないクラスは、 大規模な統合テストや UI テストで カバーできます
  • さまざまなシナリオをテストする機会が少ない。大規模なテストには時間がかかり そのため、アプリのすべての状態をテストするのは非現実的かもしれません。

アーキテクチャ ガイドラインについて詳しくは、アプリに関するガイド アーキテクチャをご覧ください。

分離へのアプローチ

関数、クラス、またはモジュールの一部を他の部分から抽出できる場合は、 その方が簡単で 効率が良くなりますこの手法は「分離」と呼ばれ、 テスト可能なアーキテクチャにとって最も重要なコンセプトです。

一般的な分離手法は次のとおりです。

  • アプリをプレゼンテーション、ドメイン、データなどのレイヤに分割します。Google Chat では また、アプリを機能ごとに 1 つのモジュールに分割します。
  • 次のような大きな依存関係を持つエンティティにはロジックを追加しない。 アクティビティとフラグメントですこれらのクラスをフレームワークへのエントリ ポイントとして使用し、 UI とビジネス ロジックをコンポーズ可能な関数、ViewModel、他の場所に移動する できます。
  • ビジネス ロジックを含むクラスで、直接的なフレームワーク依存関係を避けてください。 たとえば、ViewModel で Android コンテキストを使用しないでください
  • 依存関係を簡単に置換できるようにする。たとえば、 インターフェースを使用します。使用 DI フレームワークを使用していない場合でも、依存関係インジェクション

次のステップ

テストが必要な理由と、主に 2 種類のテストについて理解したところで、 テスト項目をご覧ください。

最初のテストを作成して実践で学習する場合は、 テスト Codelab をご覧ください。