Test Mapping

本文简要介绍了 Test Mapping,并说明了如何在 Android 开源项目 (AOSP) 中轻松开始配置测试。

什么是 Test Mapping?

Test Mapping 是一种基于 Gerrit 的方法,让开发者能够直接在 Android 源代码树中创建提交前规则和提交后规则,并将要测试的分支和设备的决策留给测试基础架构本身。Test Mapping 定义是名为 TEST_MAPPING 的 JSON 文件,该文件可放置在任何源目录中。

Atest 可以使用 TEST_MAPPING 文件在相关目录中运行提交前测试。借助 Test Mapping,您只需在 Android 源代码树中进行简单的更改,即可将同一组测试添加到提交前检查。

请参阅以下示例:

针对 services.core 将提交前测试添加到 TEST_MAPPING

通过导入针对 tools/dexter 将提交前的测试添加到 TEST_MAPPING

定义测试组

Test Mapping 组通过测试组进行测试。测试组的名称可以是任何字符串。例如,presubmit 可用于在验证更改时运行的测试组。postsubmit 测试可在更改合并后用于验证构建。

打包构建脚本规则

为了让 Trade Federation 自动化测试框架针对指定版本运行 Test Mapping 的测试模块,必须针对 Soong 将这些模块的 test_suite(或者针对 Make 将这些模块的 LOCAL_COMPATIBILITY_SUITE)设为以下两个套件之一:

  • device-tests - 针对特定设备 CPU 构建
  • general-tests - 针对任何应用二进制接口 (ABI) 构建

如有疑问,请将 gtest 放入 device-test,并将 APK 测试放入 general-test。

示例:

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

创建 Test Mapping 文件

对于需要测试覆盖的目录,只需添加与以下示例类似的 TEST_MAPPING JSON 文件即可。这些规则可以确保当此目录或其子目录中的任何文件被访问时,相应测试会在提交前检查中运行。

举个例子

以下是一个示例 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 分别是每个测试组的名称。如需详细了解测试组,请参阅定义测试组

可在 name 属性值中设置测试模块名称Trade Federation 集成测试名称(指向测试 XML 文件的资源路径,例如 uiautomator/uiautomator-demo)。请注意,不可在 name 字段中使用类 name 或测试方法 name。要缩减所运行的测试,您可以在此处使用 include-filter 等选项请参阅(include-filter 使用示例)。

测试的 host 设置指示测试是否是在主机上运行的无设备测试。默认值为 false,表示需要有设备才能运行测试。支持的测试类型为 HostGTest(适用于原生测试)和 HostTest(适用于 JUnit 测试)。

使用 file_patterns 属性,您可以设置正则表达式字符串列表,以匹配任何源代码文件的相对路径(相对于包含 TEST_MAPPING 文件的目录)。在上面的示例中,只有当任意以 Window 或 Activity 开头的 java 文件(该文件所在目录与 TEST_MAPPING 文件的目录或其子目录相同)发生更改时,测试 CtsWindowManagerDeviceTestCases 才会在提交前测试中运行。当反斜线 \ 包含在 JSON 文件中时,需要对其进行转义。

借助 imports 属性,您可以包含其他 TEST_MAPPING 文件中的测试,而无需复制相应内容。请注意,导入路径的父目录中的 TEST_MAPPING 文件也将包含在内。Test Mapping 支持嵌套导入;这意味着两个 TEST_MAPPING 文件可以互相导入,并且 Test Mapping 能够正确合并随附测试。

options 属性包含其他 TradeFed 命令行选项。

要获取指定测试可用选项的完整列表,请运行以下命令:

tradefed.sh run commandAndExit [test_module] --help

如需详细了解各选项的工作原理,请参阅 TradeFed 选项处理

使用 Atest 运行测试

要在本地执行提交前测试规则,请执行以下操作:

  1. 转到包含 TEST_MAPPING 文件的目录。
  2. 运行以下命令:
atest

在当前目录及其父目录的 TEST_MAPPING 文件中配置的所有提交前测试都会运行。Atest 将针对提交前测试找到两个测试(A 和 B)并加以运行。

要运行当前工作目录 (CWD) 和父目录中的 TEST_MAPPING 文件中的提交前测试,这是最简单的方法。Atest 会找到 CWD 及其所有父目录中的 TEST_MAPPING 文件并使用这些文件,除非 TEST_MAPPING 文件将 inherit_parent 设为 false。

构建源代码

以下示例显示了如何在源代码树中配置 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 文件中的测试。以下命令可运行两个测试(A、B)。

atest --test-mapping src/project_1

运行提交后测试规则

您还可以使用此命令运行在 src_path(默认为 CWD)及其父目录中的 TEST_MAPPING 中定义的提交后测试规则:

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

仅运行不需要设备的测试

要想仅运行针对主机配置的不需要设备的测试,可以为 Atest 使用选项 --host。如果没有此选项,Atest 将运行两种测试,即需要设备的测试和在主机上运行的不需要设备的测试。这两种测试将分别在两个独立的套件中运行。

atest [--test-mapping] --host

识别测试组

您可以在 Atest 命令中指定测试组。以下命令可运行与 directory src/project_1 中的文件相关的所有提交后测试,其中只包含一个测试 (C)。

或者,您也可以使用 :all 来运行所有测试(无论测试属于哪个组)。以下命令可运行四个测试(A、B、C、X):

atest --test-mapping src/project_1:all

包含子目录

默认情况下,如果使用 Atest 运行 TEST_MAPPING 中的测试,则系统仅运行在 CWD(或指定目录)及其父目录中的 TEST_MAPPING 文件中配置的提交前测试。如果您想运行子目录中的所有 TEST_MAPPING 文件中的测试,请使用选项 --include-subdir 强制 Atest 将这些测试一并包含在内。

atest --include-subdir

如果未使用 --include-subdir 选项,则 Atest 将仅运行测试 A。如果使用了 --include-subdir 选项,则 Atest 将运行两个测试(A、B)。

支持行级注释

您可以添加行级 // 格式的注释,以使用后面的设置描述来充实 TEST_MAPPING 文件。ATest 和 Trade Federation 会将 TEST_MAPPING 预处理为不带注释的有效 JSON 格式。为了使 JSON 文件简洁易读,仅支持行级 // 格式的注释。

示例:

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