ローカル単体テストを作成する

ローカルテストは、Android デバイスやエミュレータではなく、自分のワークステーションで直接実行されます。そのため、ローカルの Java 仮想マシン(JVM)を使用し、 Android デバイスではなくテストを実行します。ローカルテストでは アプリのロジックを高速化できますただし、外部 IP アドレスを持つ Android フレームワークでは、実行できるテストの種類に制限が設けられています。

単体テストは、コードの小さなセクション( テストをご覧ください。そのコードを実行し、結果を確認します。

単体テストは通常はシンプルですが、テスト対象のユニットがテスト可能性を考慮して設計されていない場合、セットアップに問題が生じる可能性があります。

  • 検証するコードは、テストからアクセス可能である必要があります。対象 プライベート メソッドを直接テストすることはできません。代わりに、クラスでテストし、 公開 API を使用します。
  • 単体テストを単独で実行するには、単体テストと 偽のテストやモニタリングなどの管理下にあるコンポーネントで その他のテストダブルです。これは、コードが Android フレームワークに依存している場合に特に問題になります。

Android での一般的な単体テスト戦略については、テスト項目をご覧ください。

ローカルテストの場所

デフォルトでは、ローカル単体テストのソースファイルは module-name/src/test/ に配置されます。Android Studio を使用して新しいプロジェクトを作成するときに、このディレクトリはすでに存在します。

テスト用の依存関係の追加

また、Terraform を使用してプロジェクトのテスト依存関係を JUnit テスト フレームワークによって提供される標準 API。

これを行うには、アプリのモジュールの build.gradle ファイルを開き、次のライブラリを依存関係として指定します。testImplementation 関数を使用して ローカルテストのソースセットに適用し、アプリケーションには適用できません。

dependencies {
  // Required -- JUnit 4 framework
  testImplementation "junit:junit:$jUnitVersion"
  // Optional -- Robolectric environment
  testImplementation "androidx.test:core:$androidXTestVersion"
  // Optional -- Mockito framework
  testImplementation "org.mockito:mockito-core:$mockitoVersion"
  // Optional -- mockito-kotlin
  testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
  // Optional -- Mockk framework
  testImplementation "io.mockk:mockk:$mockkVersion"
}

ローカル単体テストクラスを作成する

ローカル単体テストクラスは、JUnit 4 テストクラスとして記述します。

そのためには、1 つ以上のテストメソッドを含むクラスを作成します。通常は module-name/src/test/ に作成します。1 つのテストメソッドは @Test アノテーションで始まり、そこにはテスト対象コンポーネントの単一の側面を実施、検証するためのコードが含まれています。

次の例は、ローカル単体テストクラスを実装する方法を示しています。「 テストメソッドのemailValidator_correctEmailSimple_returnsTrue()検証試行回数 アプリ内のメソッドである isValidEmail()。テスト関数が次のレスポンスを返します。 isValidEmail() も true を返す場合は true。

Kotlin


import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class EmailValidatorTest {
  @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() {
    assertTrue(EmailValidator.isValidEmail("[email protected]"))
  }

}

Java


import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

class EmailValidatorTest {
  @Test
  public void emailValidator_CorrectEmailSimple_ReturnsTrue() {
    assertTrue(EmailValidator.isValidEmail("[email protected]"));
  }
}

読みやすいテストを作成して、アプリケーションのコンポーネントが 想定どおりの結果が返されます。次のように、アサーション ライブラリを使用して、 junit.AssertHamcrest真実。上記のスニペットは、BigQuery の junit.Assert

モック可能な Android ライブラリ

ローカル単体テストを実行すると、Android Gradle プラグインに このライブラリには、Android フレームワークのすべての API を プロジェクトで使用しているバージョン。ライブラリには、これらの API のすべての公開メソッドとクラスが保持されていますが、メソッド内のコードは削除されています。該当する場合 すべてのメソッドがアクセスされると、テストは例外をスローします。

これにより、Context などの Android フレームワーク内のクラスを参照するときにローカルテストをビルドできます。さらに重要なのは、Android クラスでモック フレームワークを使用できることです。

Android 依存関係のモック

一般的な問題は、クラスが文字列リソースを使用していることです。Google Chat では ContextgetString() メソッドを呼び出して文字列リソースを取得する クラスです。ただし、ローカルテストでは、Context やそのメソッドは Android フレームワークに属しているため使用できません。getString() の呼び出しは次のようになります。 クラスから削除しましたが、これは必ずしも現実的ではありません。解決策は、getString() メソッドが呼び出されるたびに常に同じ値を返す Context のモックまたはスタブを作成することです。

Mockable Android ライブラリと、 Mockito または MockK を使用すると、 単体テストで Android クラスのモックの動作を確認する。

Mockito を使用してローカル単体テストにモック オブジェクトを追加するには、次の手順を実施します。 プログラミング モデル:

  1. テスト環境のセットアップに記載されているように、build.gradle ファイルに Mockito ライブラリの依存関係を含めます。
  2. 単体テストクラスの定義の先頭に、 @RunWith(MockitoJUnitRunner.class) アノテーション。このアノテーションは、Mockito テストランナーに対して、フレームワークの使用が正しいことを検証し、モック オブジェクトの初期化を簡素化するように伝えるものです。
  3. Android の依存関係用のモック オブジェクトを作成するには、@Mock アノテーションを追加します。 指定する必要があります。
  4. 依存関係の動作をスタブで代用するには、when() メソッドと thenReturn() メソッドを使用して、状況に合った条件と戻り値を指定します。

次の例は、モックを使用する単体テストの作成方法を示しています。 Mockito-Kotlin で作成された Kotlin の Context オブジェクト。

import android.content.Context
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock

private const val FAKE_STRING = "HELLO WORLD"

@RunWith(MockitoJUnitRunner::class)
class MockedContextTest {

  @Mock
  private lateinit var mockContext: Context

  @Test
  fun readStringFromContext_LocalizedString() {
    // Given a mocked Context injected into the object under test...
    val mockContext = mock<Context> {
        on { getString(R.string.name_label) } doReturn FAKE_STRING
    }

    val myObjectUnderTest = ClassUnderTest(mockContext)

    // ...when the string is returned from the object under test...
    val result: String = myObjectUnderTest.getName()

    // ...then the result should be the expected one.
    assertEquals(result, FAKE_STRING)
  }
}

Mockito フレームワークの使用方法について詳しくは、Mockito API リファレンスSharedPreferencesHelperTest クラスを サンプルコードをご覧ください。また、Android テスト Codelab もお試しください。

エラー: 「Method ... not mocked」

Error: "Method ... not mocked メッセージでメソッドにアクセスしようとすると、Mockable Android ライブラリによって例外がスローされます。

スローされた例外によってテストに問題が生じる場合は、戻り値の型に応じて、メソッドで null またはゼロを返すように動作を変更できます。そのためには、プロジェクトのトップレベルの build.gradle ファイルに次の構成を追加します。

android {
  ...
  testOptions {
    unitTests.returnDefaultValues = true
  }