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 控制台

构建 CTS(AOSP 14 或更早版本)

cd /path/to/android/root
source build/envsetup.sh
make cts -j32 TARGET_PRODUCT=aosp_arm64
cts-tradefed

构建 CTS(AOSP 15 或更高版本)

cd /path/to/android/root
source build/envsetup.sh
make cts -j32 TARGET_PRODUCT=aosp_arm64 TARGET_RELEASE=target-release
cts-tradefed

请参考下表选择 target-release

分支 目标版本
android15-tests-dev ap3a

在 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。value 字段的格式与 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 测试,请包含指向您在 Google 问题跟踪器中创建的测试提案的链接,作为CTS-D 提交流程的一部分。

创建子计划

例如,您可以按如下方式在 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 中的特定类。这些测试的 Java 包名称带有 cts 后缀,类名称带有 Test 后缀。每个测试用例都包含多个测试,其中每个测试通常练习被测类的特定方法。这些测试以目录结构排列,其中测试分为不同的类别,例如“widgets”或“views”。

例如,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 注解的测试。

提交您的更改

在为 CTS 贡献更改时,请遵循提交代码更改工作流程。根据补丁适用的 API 级别选择您的开发分支

  • 对于适用于多个 API 级别的更改,请在最上游的测试分支中开发补丁。允许自动合并器将更改向下合并到 AOSP 测试分支中。有关分支列表和自动合并路径信息,请参阅发行时间表和分支信息
  • 对于适用于特定 API 级别的更改,请在提交消息中使用 DO NOT MERGERESTRICT AUTOMERGE 在正确的测试分支中开发或 cherrypick 更改。

审核人员将被分配审核您的更改,并将更改 cherrypick 到内部 Gerrit 中。

发行时间表和分支信息

CTS 发行版本遵循此时间表。

版本 API 级别 分支 频率
15 35 android15-tests-dev 季度性
14 34 android14-tests-dev 季度性
13 33 android13-tests-dev 季度性
12L 32 android12L-tests-dev 季度性
12 31 android12-tests-dev 季度性

发行期间的重要日期

  • 第一周结束时:代码冻结。在代码冻结之前合并到分支中的更改将被视为即将发布的 CTS 版本的候选版本。在代码冻结之后或在选定候选发布版本之后提交到分支的提交将被视为后续发布版本的候选版本。
  • 第二周或第三周:CTS 将在 AOSP 中发布。

自动合并流程

CTS 开发分支已设置,以便提交到每个分支的更改自动合并到更高的分支。

对于直接更改 AOSP 测试开发分支,自动合并路径为
android11-tests-dev > android12-tests-dev > android12L-tests-dev > android13-tests-dev > android14-tests-dev > android15-tests-dev

如果更改列表 (CL) 未能正确合并,则补丁的作者将收到一封电子邮件,其中包含有关如何解决冲突的说明。在大多数情况下,补丁的作者可以使用这些说明跳过有冲突的 CL 的自动合并。

如果较旧的分支需要更改,则需要从较新的分支中 cherry-pick 补丁。

对于适用于下一个 Android 版本的测试更改,在您上传建议的更改后,Google 会对其进行审核,如果获得批准,则会将其 cherrypick 到内部 Gerrit 中。