テスト マッピング

ここでは、テスト マッピングの簡単な紹介と、Android オープンソース プロジェクト(AOSP)で簡単にテスト構成を始める方法について説明します。

テスト マッピングとは

テスト マッピングは Gerrit ベースの手法であり、デベロッパーは presubmit および postsubmit のテストルールを Android ソースツリーで直接作成し、テストするブランチとデバイスの決定をテスト インフラストラクチャ自体に任せることができます。テスト マッピング定義は、任意のソース ディレクトリに配置できる TEST_MAPPING という JSON ファイルです。

ATEST は TEST_MAPPING ファイルを使用して、関連付けられたディレクトリで送信前テストを実行できます。テスト マッピングを使用すると、Android ソースツリー内で簡単な変更を行うだけで、同じテストセットを presubmit チェックに追加できます。

次の例をご覧ください。

services.core の presubmit テストを TEST_MAPPING に追加する

imports を使用した tools/dexter の presubmit テストを TEST_MAPPING に追加する

テスト マッピングによるテスト実行と結果レポートは、Trade Federation(TF)テストハーネスを利用しています。

テストグループの定義

テスト マッピングは、テストグループによってテストをグループ化します。テストグループの名前には任意の文字列を使用できます。たとえば、presubmit は変更の検証時に実行するテストグループです。また、postsubmit は、変更を統合した後にビルドを検証するテストです。

ビルド スクリプト ルールのパッケージ化

Trade Federation Test Harness で指定ビルドに対してテスト マッピングのテスト モジュールを実行するには、モジュールで、Soong の場合 test_suite を、Make の場合 LOCAL_COMPATIBILITY_SUITE を次の 2 つのテストスイートのいずれかに設定する必要があります。

  • device-tests - 特定デバイスの CPU に対してビルドされる
  • general-tests - 任意のアプリケーション バイナリ インターフェース(ABI)に対してビルドされる

不明な場合は、gtests を device-tests に、APK テストを general-tests に配置します。

例:

Android.bp: test_suites: ["device-tests"],
    Android.mk: LOCAL_COMPATIBILITY_SUITE := device-tests
    

テスト マッピング ファイルの作成

テスト用のカバレッジを必要とするディレクトリの場合、以下の例のような TEST_MAPPING JSON ファイルを追加します。こうしたルールを使用すると、対象ディレクトリやサブディレクトリ内の任意のファイルにアクセスしたときに、presubmit チェックでテストを実行できます。

例による説明

TEST_MAPPING ファイルの例を次に示します。

{
      "presubmit": [
        {
          "name": "CtsWindowManagerDeviceTestCases",
          "options": [
            {
              "include-annotation": "android.platform.test.annotations.RequiresDevice"
            }
          ],
          "file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
        },
        {
          "name" : "net_test_avrcp",
          "host" : true
        }
      ],
      "postsubmit": [
        {
          "name": "CtsWindowManagerDeviceTestCases"
        }
      ],
      "imports": [
        {
          "path": "frameworks/base/services/core/java/com/android/server/am"
        }
      ]
    }
    

属性の設定

上記の例の presubmitpostsubmit は各テストグループの名前です。テストグループの詳細については、テストグループの定義をご覧ください。

テスト モジュール名前Trade Federation 統合テスト名uiautomator-uiautomator-demo など、テスト XML ファイルへのリソースパス)は、name 属性の値で設定できます。name フィールドではクラス name またはテストメソッド name を使用できません。実行するテストを絞り込む場合は、ここで include-filter などのオプションを使用できます。include-filter の使用例をご覧ください。

テストの host 設定は、テストがホストで実行されるデバイスレス テストかどうかを示します。デフォルト値は false で、この場合はテストを実行するデバイスが必要です。サポートされているテストの種類は、ネイティブ テストの場合は HostGTest、JUnit テストの場合は HostTest です。

file_patterns 属性を使用すると、任意のソースコード ファイルの相対パス(TEST_MAPPING ファイルを含むディレクトリへの相対パス)に一致する正規表現文字列のリストを設定できます。上記例のテスト CtsWindowManagerDeviceTestCases は、TEST_MAPPING ファイルと同じディレクトリまたはそのサブディレクトリに存在する Java ファイル名が Window または Activity で始まる場合にのみ、presubmit でテストが実行されます。JSON ファイル内の設定につき、バックスラッシュ \ はエスケープする必要があります。

imports 属性を使用すると、コンテンツをコピーせずにテストを他の TEST_MAPPING ファイルに含めることができます。インポートされたパスの親ディレクトリにある TEST_MAPPING ファイルも含まれますので、ご注意ください。テスト マッピングでは、インポートのネストが可能です。つまり、2 つの TEST_MAPPING ファイルが互いにインポートでき、テスト マッピングに含まれるテストを適切に統合できます。

options 属性には、追加の TradeFed コマンドライン オプションが含まれます。

特定のテストで使用可能なオプションの全リストを取得するには、次のコマンドを実行します。

    tradefed.sh run commandAndExit [test_module] --help
    

オプションの仕組みについては、TradeFed オプションの扱いをご覧ください。

Atest を使用したテストの実行

presubmit テストルールをローカルで実行するには:

  1. TEST_MAPPING ファイルが含まれているディレクトリに移動します。
  2. 次のコマンドを実行します。
    atest
    

現ディレクトリと親ディレクトリの TEST_MAPPING ファイルで構成されているすべての presubmit テストが実行されます。Atest は、presubmit の 2 つのテスト(A と B)を見つけて実行します。

これは、現在の作業ディレクトリ(CWD)と親ディレクトリにある TEST_MAPPING ファイルで presubmit テストを実行する最も簡単な方法です。TEST_MAPPING ファイルの inherit_parent が false に設定されていない限り、Atest は CWD とすべての親ディレクトリ内の TEST_MAPPING ファイルを見つけて使用します。

ソースコードの構造化

次の例は、ソースツリー全体で TEST_MAPPING ファイルを構成する方法を示しています。

src
    ├── project_1
    │   └── TEST_MAPPING
    ├── project_2
    │   └── TEST_MAPPING
    └── TEST_MAPPING
    

src/TEST_MAPPING のコンテンツ:

{
      "presubmit": [
        {
          "name": "A"
        }
      ]
    }
    

src/project_1/TEST_MAPPING のコンテンツ:

{
      "presubmit": [
        {
          "name": "B"
        }
      ],
      "postsubmit": [
        {
          "name": "C"
        }
      ],
      "other_group": [
        {
          "name": "X"
        }
      ]}
    

src/project_2/TEST_MAPPING のコンテンツ:

{
      "presubmit": [
        {
          "name": "D"
        }
      ],
      "import": [
        {
          "path": "src/project_1"
        }
      ]}
    

ターゲット ディレクトリの指定

ターゲット ディレクトリを指定して、そのディレクトリ内の TEST_MAPPING ファイルでテストを実行できます。次のコマンドは、2 つのテスト(A、B)を実行します。

    atest --test-mapping src/project_1
    

postsubmit テストルールの実行

このコマンドを使用して、src_path(デフォルトは CWD)と親ディレクトリの TEST_MAPPING で定義されている postsubmit テストルールを実行することもできます。

    atest [--test-mapping] [src_path]:postsubmit
    

デバイスを必要としないテストのみ実行する

Atest の --host オプションを使用して、デバイスを必要としないホストに対して構成されたテストのみを実行できます。このオプションを指定しない場合、Atest はデバイスを必要とするテスト、ホスト上で実行されデバイスを必要としないテストの両方を実行します。テストは、2 つの独立したスイートで実行されます。

    atest [--test-mapping] --host
    

テストグループの特定

テストグループは、Atest コマンドで指定できます。次のコマンドは、src/project_1 ディレクトリにあるファイルに関連する postsubmit テストをすべて実行します。このディレクトリには、テストが 1 つだけ(C)含まれています。

または、:all を使用すると、グループに関係なくすべてのテストを実行できます。次のコマンドは、4 つのテスト(A、B、C、X)を実行します。

    atest --test-mapping src/project_1:all
    

サブディレクトリを含める

デフォルトでは、Atest を使用して TEST_MAPPING 内のテストを実行すると、CWD(または指定ディレクトリ)と親ディレクトリの TEST_MAPPING ファイルで構成された presubmit テストのみが実行されます。サブディレクトリにあるすべての TEST_MAPPING ファイル内のテストを実行する場合は、--include-subdir オプションを使用して強制的に Atest によるテストの対象に含めます。

    atest --include-subdir
    

--include-subdir オプションを指定しない場合、Atest はテスト A のみを実行します。--include-subdir オプションを指定した場合は、2 つのテスト(A、B)を実行します。

行レベルのコメントのサポート

行レベルの // 形式のコメントを使用して、以下のように TEST_MAPPING ファイルに設定の説明を追加できます。ATest と Trade Federation は TEST_MAPPING を前処理して、コメントがない有効な JSON 形式にします。JSON ファイルをわかりやすく読みやすくするため、行レベルの // 形式コメントのみがサポートされています。

例:

{
      // For presubmit test group.
      "presubmit": [
        {
          // Run test on module A.
          "name": "A"
        }
      ]
    }