Save the date! Android Dev Summit is coming to Mountain View, CA on November 7-8, 2018.

Testing Support Library

Android Testing Support Library は Android アプリのテストに役立つ広範囲にわたるフレームワークを提供しています。アプリのテストコードを迅速に作成して実行できるよう、一連の API を提供しており、UJnit 4 テストおよび機能 UI テストが備わっています。これらの API で作成したテストは Android Studio IDE またはコマンドラインから実行できます。

Android Testing Support Library は、Android SDK Manager から入手できます。詳細については、Testing Support Library の設定をご覧ください。

このページでは Android Testing Support Library で提供しているツール、テスト環境での使用方法、ライブラリのリリース情報について説明します。

Testing Support Library の機能

Android Testing Support Library には、次のテスト自動化ツールが含まれています。

  • AndroidJUnitRunner:Android 用 JUnit4-compatible テストランナー
  • Espresso:アプリの機能 UI テストに最適な UI テスト フレームワーク
  • UI Automator:システムやインストールされた複数のアプリにまたがる機能 UI テストに最適な UI テスト フレームワーク

AndroidJUnitRunner

AndroidJUnitRunner クラスは Android 端末上で JUnit 3 または JUnit 4-style のテストクラスを実行する JUnit テストランナーです。EspressoUI Automator テスト フレームワークを使用している場合も使えます。テストランナーとはテスト パッケージおよびテスト段階のアプリを端末に読み込み、テストを実行して、結果を報告するものです。このクラスは JUnit 3 テストのみをサポートしていた InstrumentationTestRunner クラスに代わるものです。

テストランナーの主要な機能は次のとおりです。

Android 2.2(API レベル 8)以降が必要です。

JUnit サポート

テストランナーは JUnit 3 and JUnit 4(JUnit 4.10 まで)テストと互換性があります。ただし、JUnit 3 と JUnit 4 のテストコードを同じパッケージ内で一緒に使うことは避けてください。予期しない状態に陥る場合があります。端末やエミュレータ上で実行するインストルメント化した JUnit 4 テストクラスを作成する際は、テストクラスの先頭に @RunWith(AndroidJUnit4.class) アノテーションを付けてください。

以下のコード スニペットは、CalculatorActivity クラスの add 処理が正常に機能することを確認するために、インストルメント化した JUnit 4 テストを作成する方法を示しています。

import android.support.test.runner.AndroidJUnit4;
import android.support.test.runner.AndroidJUnitRunner;
import android.test.ActivityInstrumentationTestCase2;

@RunWith(AndroidJUnit4.class)
public class CalculatorInstrumentationTest
        extends ActivityInstrumentationTestCase2<CalculatorActivity> {

    @Before
    public void setUp() throws Exception {
        super.setUp();

        // Injecting the Instrumentation instance is required
        // for your test to run with AndroidJUnitRunner.
        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
        mActivity = getActivity();
    }

    @Test
    public void typeOperandsAndPerformAddOperation() {
        // Call the CalculatorActivity add() method and pass in some operand values, then
        // check that the expected value is returned.
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }
}

インストルメンテーション情報へのアクセス

テストの実行に関する情報にアクセスするには、InstrumentationRegistry クラスを使用します。このクラスには、Instrumentation オブジェクト、ターゲット アプリの Context オブジェクト、テストアプリの Context オブジェクト、テストに渡すコマンドラインの引数が含まれます。これらのデータは、UI Automator フレームワークを使ってテストを作成するときや、InstrumentationContext オブジェクトへの依存関係があるテストを作成する際に役立ちます。

テストフィルタ

JUnit 4.x テストでは、アノテーションを使用してテスト実行の設定をすることができます。この機能により、定型コードや条件コードをテストに追加する必要性を最小限に抑えることができます。Junit 4 でサポートされている標準のアノテーションに加え、テストランナーは次のような Android 特有のアノテーションをサポートします。

  • @RequiresDevice: エミュレータ上ではなく、実機上でのみでテストを実行するよう指定します。
  • @SdkSupress: テストを実行する最低限の Android API レベルを指定します。たとえば @SDKSupress(minSdkVersion=18) アノテーションを使用した場合は、API レベルが 18 未満であればテストを実施しません。
  • @SmallTest@MediumTest@LargeTest: テストの実行にかかる時間、すなわちテストを実施する頻度の区分を指定します。

テスト シャーディング

テストランナーでは 1 つのテストを複数のシャードに分割できるため、同じシャードに属するテストをグループ化して、同じ Instrumentation インスタンスで同時に簡単に実行できます。それぞれのシャードはインデックス番号で識別します。テストの実行時には、-e numShards を使って分割したシャードの数を指定し、-e shardIndex オプションで実行するシャードを指定します。

たとえば、テスト スイートを 10 個のシャードに分割して、2 番目のシャードにグループ化されたテストだけを実行したい場合は、次のコマンドを使用します。

adb shell am instrument -w -e numShards 10 -e shardIndex 2

テストランナーの詳細な使用法は、API リファレンスをご覧ください。

Espresso

Espresso テスト フレームワークには、アプリ内のユーザー フローを評価するための UI テスト作成に役立つ API が用意されています。これらの API を使用すると、簡潔で確実に動作する自動化 UI テストを作成できます。Espresso はホワイトボックス スタイルの自動化テストの作成に適したフレームワークで、テスト対象となるアプリの実装コードの細部をテストコードとして利用しています。

Espresso テスト フレームワークの主な機能は次のとおりです。

  • ビューに対応した柔軟性のある API とターゲット アプリでのアダプタ マッチング詳細については、ビュー マッチングをご覧ください。
  • UI インタラクションを自動化する多様なアクション API詳細については、アクション APIをご覧ください。
  • テストの信頼性を向上させる UI スレッドの同期詳細については、UI スレッドの同期をご覧ください

Android 2.2(API レベル 8)以降が必要です。

ビュー マッチング

Espresso.onView() メソッドを使用すると、ターゲットのアプリの UI コンポーネントにアクセスして操作することができます。Matcher 引数をとり、ビュー階層を検索して、指定した条件を満たす View インスタンスを探します。次のような条件を指定すると、検索精度が上がります。

  • ビューのクラス名
  • ビューのコンテンツ説明
  • ビューの R.id
  • ビューに表示されるテキスト

たとえば、my_button という ID 値を持つボタンを対象にするには、次のようにマッチャーを指定します。

onView(withId(R.id.my_button));

検索が成功して onView() メソッドがリファレンスを返すと、ユーザー アクションの実行と、アサーションによるターゲット ビューのテストの実施が可能になります。

アダプタ マッチング

AdapterView レイアウトでは、実行中に子ビューが動的にレイアウトに追加されます。ターゲット ビューが、AdapterViewListViewGridView など)からサブクラス化したレイアウト内にある場合は、onView() メソッドが機能しないことがあります。これは、レイアウト ビューのサブセットのみが現在のビュー階層に読み込れるためです。

ターゲット ビューの要素にアクセスするには、代わりに Espresso.onData() メソッドを使用してください。Espresso.onData() メソッドがリファレンスを返すと、ユーザー アクションの実行とアサーションによる AdapterView 内の要素に対するテストの実施が可能になります。

アクション API

一般的にアプリをテストする際は、アプリのユーザー インターフェースにおいて、さまざまなユーザー操作を行います。ViewActions API を使うと、これらのテスト操作を簡単に自動化できます。実行できる UI インタラクションには次のものが含まれます。

  • ビューのクリック
  • スワイプ
  • キーとボタンの押下
  • テキスト入力
  • リンクを開く

たとえば以下のような自動化テスト用のスクリプトを作成すると、文字列を入力して、その値をボタン押して送信する操作をシミュレーションできます。ViewInteraction.perform() および DataInteraction.perform() メソッドは 1 つ以上の ViewAction 引数をとり、指定された順番でアクションを実行します。

// Type text into an EditText view, then close the soft keyboard
onView(withId(R.id.editTextUserInput))
    .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard());

// Press the button to submit the text change
onView(withId(R.id.changeTextBt)).perform(click());

UI スレッドの同期

Android 端末上でのテストは、タイミングの問題で偶然失敗することがあります。こうした状況は「不安定なテスト」として問題になっています。Espresso 以前は、十分な長さのスリープやタイムアウト時間をテストの中に設ける、またはコードを追加して失敗した操作を引き続き再試行するなどの回避策をとっていました。Espresso テスト フレームワークでは Instrumentation と UI スレッド間の同期を処理するため、以前のようなタイミングによる回避策をとらずに、より信頼性の高い形で確実にテスト アクションとアサーションを実行できます。

Espresso の詳しい使用方法は、API リファレンスおよび 単一アプリの UI テストのトレーニングをご覧ください。

UI Automator

UI Automator テスト フレームワークには、ユーザーアプリおよびシステムアプリ上でインタラクションを行う UI テストの作成に役立つ API が用意されています。UI Automator API を使用すると、テスト端末上で設定メニューやアプリ ランチャーを開くなどの操作が可能になります。UI Automator テスト フレームワークは、ブラックボックス スタイルの自動化テストの作成に適したフレームワークで、テストコードはターゲット アプリ内部の詳細な実装内容に依存しません。

UI Automator テスト フレームワークの主要な機能は次のとおりです。

  • レイアウト階層を精査するビューア詳細については、UI Automator ビューアをご覧ください。
  • ターゲット端末上で状態情報を取得し、操作を実行する API詳細については、 端末状態へのアクセスをご覧ください。
  • 複数のアプリにまたがる UI テストをサポートする API詳細については、 UI Automator API をご覧ください。

Android 4.3(API レベル 18)以降が必要です。

UI Automator ビューア

uiautomatorviewer ツールは Android 端末上に現在表示されている UI コンポーネントをスキャンし、分析するのに便利な GUI を提供しています。このツールを使用すると、レイアウト階層を精査し、端末のフォアグラウンドに表示されている UI コンポーネントのプロパティを見ることができます。これらの情報と UI Automator を活用すると、特定の可視プロパティに対応する UI セレクタを作成するなど、より詳細なテストの作成が可能になります。

uiautomatorviewer ツールは、<android-sdk>/tools/ ディレクトリ内にあります。

端末状態へのアクセス

UI Automator テスト フレームワークは、ターゲットアプリを実行する端末へのアクセスと操作を行うための UiDevice クラスを提供します。このクラスのメソッドを呼び出すと、現在の画面の向きや画面サイズなどの端末プロパティにアクセスできます。UiDevice クラスでは、次のようなアクションを実行することもできます。

  • 端末の回転の変更
  • D-pad ボタンのクリック
  • Back、Home、Menu ボタンのクリック
  • 通知シェードを開く
  • 現在のウィンドウのスクリーンショット撮影

たとえば、Home ボタンのクリックをシミュレーションするには UiDevice.pressHome() メソッドを呼び出します。

UI Automator API

UI Automator API を使用すると、ターゲット アプリの実装を詳細まで把握していなくても、確実なテストを作成することが可能です。これらの API は、複数のアプリにわたる UI コンポーネントのキャプチャや操作に使用できます。

  • UiCollection: コンテナの UI 要素を列挙して、可視テキストや contentDescription 属性によって、子要素を数え上げ、ターゲットにします。
  • UiObject: 端末上に表示される UI 要素を表します。
  • UiScrollable: スクロール可能な UI コンテナ内のアイテムの検索をサポートします。
  • UiSelector: 端末上にある 1 つ以上の対象 UI 要素を特定するための検索条件を表します。
  • Configurator: UI Automator テストを実行するための主要なパラメータを設定できるようにします。

たとえば次のコードを参考に、デフォルトのアプリ ランチャーを端末に表示するテスト スクリプトを作成することができます。

// Initialize UiDevice instance
mDevice = UiDevice.getInstance(getInstrumentation());

// Perform a short press on the HOME button
mDevice.pressHome();

// Bring up the default launcher by searching for
// a UI component that matches the content-description for the launcher button
UiObject allAppsButton = mDevice
        .findObject(new UiSelector().description("Apps"));

// Perform a click on the button to bring up the launcher
allAppsButton.clickAndWaitForNewWindow();

UI Automator の詳しい使用方法は、API リファレンスおよび 複数アプリの UI テストのトレーニングをご覧ください。

Testing Support Library のセットアップ

Android Testing Support Library のパッケージは最新の Android Support Repository に含まれており、Android SDK Manager から追加でダウンロードできます。

Android Support Repository を SDK Manager からダウンロードする方法:

  1. Android SDK Manager を起動します。
  2. [SDK Manager] ウィンドウで [Packages] リストを番下までスクロールし、「Extras」フォルダを探して、必要に応じてコンテンツが表示されるように展開します。
  3. [Android Support Repository] アイテムを選択します。
  4. [Install packages...] ボタンをクリックします。

ダウンロードが完了すると、ツールによって既存の Android SDK ディレクトリに Support Repository ファイルがインストールされます。ライブラリ ファイルは、SDK のサブディレクトリである <sdk>/extras/android/m2repository ディレクトリ内に格納されます。

Android Testing Support Library のクラスは android.support.test パッケージの配下にあります。

Android Testing Support Library を Gradle プロジェクトで使用するには、以下の依存関係を build.gradle ファイルに追加してください。

dependencies {
  androidTestCompile 'com.android.support.test:runner:0.4'
  // Set this dependency to use JUnit 4 rules
  androidTestCompile 'com.android.support.test:rules:0.4'
  // Set this dependency to build and run Espresso tests
  androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
  // Set this dependency to build and run UI Automator tests
  androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
}

Gradle プロジェクトで AndroidJUnitRunner をデフォルトのテスト インストルメンテーション ランナーとして設定するには、以下の依存関係を build.gradle ファイルに追加してください。

android {
    defaultConfig {
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
}

Android Testing Support Library と Android Studio IDE を併用することを強く推奨します。Android Studio には、次のようなテスト開発をサポートする機能があります。

  • テストコードの依存関係の管理をサポートする Gradle ベースの柔軟なビルド システム
  • 単体テストとインストルメント化されたテストのコード、アプリのソースコードを含む単一のプロジェクト構造
  • コマンドラインまたはグラフィック ユーザー インターフェースからの、仮想端末および実機環境へのテストの展開と実行をサポート

Android Studio の詳細情報およびダウンロードについては、Android Studio と SDK Tools のダウンロード をご覧ください。