CTS 开发

初始化您的 Repo 客户端

请按照下载源代码中的说明进行操作,以获取并构建 Android 源代码。发出 repo init 命令时,请使用 -b 指定具体的 CTS 分支。这样可以确保将您的 CTS 更改纳入到后续 CTS 版本中。

以下示例代码展示了如何使用 repo init

mkdir android11-tests-dev && cd android11-tests-dev && repo init -c -u https://android.googlesource.com/platform/manifest -b android11-tests-dev --use-superproject --partial-clone --partial-clone-exclude=platform/frameworks/base --clone-filter=blob:limit=10M && repo sync -c -j8

构建和运行 CTS

执行以下命令以构建 CTS 并启动交互式 CTS 控制台:

cd /path/to/android/root
make cts -j32 TARGET_PRODUCT=aosp_arm64
cts-tradefed

在 CTS 控制台中,输入以下命令:

tf> run cts --plan CTS

编写 CTS 测试

CTS 测试使用 JUnit 和 Android 测试 API。请查看 cts/tests 目录下的测试应用教程和现有测试。CTS 测试大部分情况下都遵循其他 Android 测试中使用的相同规范。

CTS 可在多种正式版设备上运行,因此测试必须遵循以下规则:

  • 考虑不同的屏幕尺寸、屏幕方向和键盘布局。
  • 仅使用公共 API 方法。也就是说,避免使用任何带有 hide 注解的类、方法和字段。
  • 避免使用视图布局或者依赖可能不适合某些设备的资源尺寸。
  • 请勿依赖 root 特权。

添加 Java 注解

如果您的测试会验证 API 行为,请使用 @ApiTest 为测试代码添加注解,并在 apis 字段中列出涉及的所有 API。请使用以下示例中相应的格式:

API 类型 注解格式 备注
方法 android.example.ClassA#methodA 最常见的用例。
包含键值对的方法 android.example.ClassB#methodB(KeyA) 仅在测试会使用 API 方法来验证字段时使用,如此示例所示。
字段 android.example.ClassC#FieldA 仅在测试会直接验证 API 字段时使用,如此示例所示。

如果您的测试会验证 CDD 要求,请在 CTS 测试代码中使用 @CddTest 为要求 ID(包括 CDD 小节 ID 和要求 ID)添加注解,如以下示例所示。在您的提交消息中,请通过引用 CDD 要求 ID 来提及您的测试会验证的 CDD 要求。CDD 要求 ID 由小节 ID 和要求 ID 组成,由斜杠 (/) 连接,如 7.3.1/C-1-1 中所示。


/**
* Verify Passpoint configuration management APIs for a Passpoint
* @throws Exception
*/
    @CddTest(requirement="7.4.2.3/C-1-1,C-2-1")
    public void testAddPasspointConfigWithUserCredential() throws Exception {
        if (!WifiFeature.isWifiSupported(getContext())) {
            // skip the test if WiFi is not supported
            return;
        }      testAddPasspointConfig(generatePasspointConfig(generateUserCredential()));
    }

对于 CTS 验证程序,请使用相关 CDD ID 为 AndroidManifest.xml 中的每个 activity 添加注解。值字段的格式与 CTS 中 Java 注解的格式类似。在提交消息中,请通过引用 CDD 要求 ID 来提及要强制执行的 CDD 要求。


  <activity>
    ......
    <!-- OPTIONAL: Add a meta data attribute to indicate CDD requirements. -->
    <meta-data android:name="cdd_test" android:value="7.4.1/C-4-1" />

    <!-- OPTIONAL: Add a meta data attribute to indicate APIs being tested. -->
    <meta-data android:name="api_test"
               android:value="com.example.MyClass#myMethod" />

    <!-- OPTIONAL: Add a metadata attribute to indicate the reason why the test doesn't enforce any CDD requirement but still useful in CTS-V. -->
    <meta-data android:name="non_compliance_test"
               android:value="detailed reasons" />
  </activity>

在提交消息中

您要明确提及需要添加测试的原因,并添加相关链接以提供支持。对于 CTS-D 测试,请附上您在 CTS-D 提交流程中从 Google 问题跟踪器中创建的测试方案的链接。

创建子计划

例如,您可以在 android-cts/subplans 中添加一个 SubPlan.xml 文件,如下所示:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<SubPlan version="2.0">
<Entry include="CtsSystemIntentTestCases" />
<Entry include="CtsSystemUiHostTestCases" />
<Entry include="CtsSecurityHostTestCases android.security.cts.SELinuxHostTest#testAospFileContexts" />
<Entry include="CtsSecurityHostTestCases android.security.cts.SELinuxHostTest#testAospServiceContexts" />
</SubPlan>

如需运行该子计划,请执行以下操作:

run cts --subplan aSubPlan

子计划条目格式如下:

Include a module name as follows:
<Entry include="MODULE_NAME" />

Include a package:
<Entry include="MODULE_NAME PACKAGE_NAME" />

Include a class:
<Entry include="MODULE_NAME PACKAGE_NAME.CLASS_NAME" />

Include an individual test:
<Entry include="MODULE_NAME PACKAGE_NAME.CLASS_NAME#TEST_NAME" />

测试命名和位置

大多数 CTS 测试用例都针对 Android API 中的特定类进行测试。这些测试具有以 cts 为后缀的 Java 软件包名称和以 Test 为后缀的类名称。每个测试用例包含多个测试,其中每个测试通常会执行被测类的某个特定方法。这些测试按目录结构进行组织并被划分为不同的类别,例如“widget”或“视图”。

例如,Java 软件包 android.widget.TextView 的 CTS 测试为 android.widget.cts.TextViewTest,其 Java 软件包名称为 android.widget.cts,其类名称为 TextViewTest

  • Java 软件包名称
    CTS 测试的 Java 软件包名称是被测类的软件包名称后面加上 .cts。在我们的示例中,软件包名称为 android.widget.cts
  • 类名称
    CTS 测试的类名称是被测类的名称后面加上“Test”。例如,如果某项测试的测试目标是 TextView,类名称就应为 TextViewTest
  • 模块名称(仅限 CTS v2)
    CTS v2 按模块对测试进行组织。模块名称通常是 Java 软件包名称的第二个字符串(在我们的示例中为 widget)。

具体的目录结构和代码示例取决于您使用的是 CTS v1 还是 CTS v2。

CTS v1

对于 Android 6.0 或更低版本,请使用 CTS v1。对于 CTS v1,代码示例位于 cts/tests/tests/example 下。

CTS v1 测试中的目录结构如下所示:

cts/
  tests/
    tests/
      package-name/
        Android.mk
        AndroidManifest.xml
        src/
          android/
            package-name/
              SampleDeviceActivity.java
              cts/
                SampleDeviceTest.java

CTS v2

对于 Android 7.0 或更高版本,请使用 CTS v2。如需了解详情,请参阅 Android 开源项目 (AOSP) 中的示例测试

CTS v2 目录结构如下所示:

cts/
  tests/
    module-name/
      Android.mk
      AndroidManifest.xml
      src/
        android/
          package-name/
            SampleDeviceActivity.java
            cts/
              SampleDeviceTest.java

新建示例软件包

添加新测试时,可能没有现成的目录放置测试。在这种情况下,您需要创建目录并复制相应的示例文件。

CTS v1

您如果使用的是 CTS v1,请参照 cts/tests/tests/example 下的示例创建一个新目录。此外,请确保将位于 Android.mk 的新软件包模块名称添加到 cts/CtsTestCaseList.mk 中的 CTS_COVERAGE_TEST_CASE_LISTbuild/core/tasks/cts.mk 会使用此 Makefile 将所有测试组合在一起,并创建最终 CTS 软件包。

CTS v2

参照测试示例 /cts/tests/sample/ ,按照以下步骤快速开始构建新的测试模块:

  1. 如需创建测试目录并复制示例文件,请运行以下命令:
    mkdir cts/tests/module-name && cp -r cts/tests/sample/* cts/tests/module-name
  2. 转到 cts/tests/module-name,然后按照上文建议的命名惯例替换所有出现的“[Ss]ample”。
  3. 更新 SampleDeviceActivity 以运行您需要测试的功能。
  4. 更新 SampleDeviceTest 以确保该 Activity 成功或记录其错误。

其他目录

此外,您还可以添加其他 Android 目录,如 assetsjnilibsres。如需添加 JNI 代码,请在项目根目录下的 src 旁创建一个目录,并将原生代码和 Android.mk Makefile 放入该目录中。

Makefile 通常包含以下设置:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libCtsSample_jni

# don't include this package in any target
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := list of source code files
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)

# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts
LOCAL_SHARED_LIBRARIES := libnativehelper
LOCAL_SDK_VERSION := current
include $(BUILD_SHARED_LIBRARY)

Android.mk 文件

最后,按如下所示修改项目根目录下的 Android.mk 文件,以构建原生代码并依赖于该代码:

# All tests should include android.test.runner.
LOCAL_JAVA_LIBRARIES := android.test.runner

# Includes the jni code as a shared library
LOCAL_JNI_SHARED_LIBRARIES := libCtsSample_jni

# Include for InstrumentationCtsTestRunner
LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner...
LOCAL_SDK_VERSION := currentinclude $(BUILD_CTS_PACKAGE)

#Tells make to look in subdirectories for more make files to include
include $(call all-makefiles-under,$(LOCAL_PATH))

修复或移除测试

除添加新测试之外,您还可以修复或移除带有 BrokenTestKnownFailure 注解的测试。

提交更改

在 AOSP 中提交 CTS 或 VTS 补丁时,请根据补丁适用的 API 级别选择您的开发分支。

  • 对于适用于多个 API 级别的更改,请先aosp/main 中开发补丁,然后为最上游的测试分支择优挑选补丁程序。允许自动合并器合并 AOSP 测试分支中的下游更改。如需获取分支列表和有关自动合并路径的信息,请参阅发布时间表和分支信息
  • 对于具体到某一特定 API 级别的更改,请在正确的测试分支中开发或择优挑选更改,并在提交消息中添加 DO NOT MERGERESTRICT AUTOMERGE

按照提交补丁工作流程向 CTS 提交更改。我们会指定审核人员,对您的更改进行相应审核。

发布时间表和分支信息

CTS 的发布遵循以下时间表。

版本 API 级别 分支 频率
14 34 android14-tests-dev 每季度
13 33 android13-tests-dev 每季度
12L 32 android12L-tests-dev 每季度
12 31 android12-tests-dev 每季度
11 30 android11-tests-dev 每季度
对于版本 10.0、9.0、8.1、8.0、7.1、7.0、6.0、5.1、5.0、4.4、4.3 和 4.2,尚无对应的后续发布计划。

发布过程中的重要日期

  • 第一周结束:代码冻结。在代码冻结之前合并到分支的更改会应用到即将发布的 CTS 版本中。相关更改如果在代码冻结或确定了候选发布版本之后才提交到分支,则会应用到后续版本中。
  • 第二周或第三周:在 AOSP 中发布 CTS。

自动合并流程

我们对 CTS 开发分支做了相应的设置,使提交到每个分支的更改自动合并到更高的分支中。

对于直接提交到 AOSP 测试开发者分支的更改,自动合并路径为:
android11-tests-dev > android12-tests-dev > android12L-tests-dev > android13-tests-dev > android14-tests-dev > aosp/main

对于仅针对下一个 Android 版本的更改,自动合并路径为:
aosp/main > <Internal git/main>

如果变更列表 (CL) 未能正确合并,补丁的作者会收到一封说明如何解决冲突的电子邮件。在大多数情况下,补丁的作者可以按照这些说明跳过冲突 CL 的自动合并。

如果较旧的分支需要相关的更改,就需要从较新的分支中择优挑选补丁。