多设备套件

该文档提供了有关如何创建多设备模块的分步说明,并在已知时指出了当前限制。

样本

提供了一个 CTS wifi 感知多设备模块。它通过 wifi 从一个设备发送一条消息,并验证另一台设备接收到它。

该模块的来源位于cts/hostsidetests/multidevices/wifi_aware

我们已经用我们认为有用的注释对示例进行了注释。

第一步:创建模块文件夹

建议在它所属的套件项目中为您的多设备模块创建一个文件夹。例如: cts/hostsidetests/multidevices/ 。我们建议这样做,以便所有多设备模块至少在开始时保持并置,这将更容易发现示例。

这个模块的所有文件都应该放在他们自己的模块文件夹下。例如: wifi_aware

通常需要模块的 OWNERS 文件,并且必须在其中指定错误组件。有关示例,请参阅cts/hostsidetests/multidevices/wifi_aware/OWNERS

第 2 步:创建测试

这是您实现测试逻辑的地方。它高度依赖于正在测试的内容。

创建 Mobly 测试源,例如: wifi_aware_test.py

第 3 步:创建构建文件:Android.bp

添加一个 Android.bp 文件,例如cts/hostsidetests/multidevices/wifi_aware/Android.bp 。定义一个 python_test_host 模块,类似于:

python_test_host {
    name: "CtsWifiAwareTestCases",
    main: "wifi_aware_test.py",
    srcs: ["wifi_aware_test.py"],
    test_suites: [
        "cts",
        "general-tests",
    ],
    test_options: {
        unit_test: false,
    },
    data: [
          // Package the snippet with the mobly test
        ":wifi_aware_snippet",
    ],
}

使用数据字段指定测试的片段,该片段将与二进制文件一起打包,并且可以通过 ATest 或在持续执行中定位和安装在测试中。

Mobly Bundled Snippets 在 Android 中位于external/mobly-bundled-snippets/

可选:创建自定义片段

一些多设备模块可能需要自定义 Mobly 片段。示例测试在cts/hostsidetests/multidevices/wifi_aware/snippet/处包含一个 wifi 感知片段,该片段是使用 Mobly Snippet Lib 构建的,在 Android 中可在以下位置获取: external/mobly-snippet-lib/

该片段应使用 Android.bp 中的 android_test 规则定义,如标准检测:

android_test {
    name: "wifi_aware_snippet",
    sdk_version: "current",
    srcs: [
        "CallbackUtils.java",
        "WifiAwareSnippet.java",
    ],
    manifest: "AndroidManifest.xml",
    static_libs: [
        "androidx.test.runner",
        "guava",
        "mobly-snippet-lib",
    ],
}

第 4 步:创建模块配置:AndroidTest.xml

添加一个 AndroidTest.xml 文件,例如cts/hostsidetests/multidevices/wifi_aware/AndroidTest.xml 。在此测试配置中,您需要指定两个设备进行测试,类似于:

<configuration description="Config for CTS Wifi Aware test cases">
    <option name="test-suite-tag" value="cts" />
    <option name="config-descriptor:metadata" key="component" value="wifi" />
    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
    <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />

    <device name="device1">
        <!-- For coverage to work, the APK should not be uninstalled until after coverage is pulled.
             So it's a lot easier to install APKs outside the python code.
        -->
        <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
            <option name="test-file-name" value="wifi_aware_snippet.apk" />
        </target_preparer>
        <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
            <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
            <option name="run-command" value="wm dismiss-keyguard" />
        </target_preparer>
        <target_preparer class="com.android.tradefed.targetprep.PythonVirtualenvPreparer">
          <!-- Any python dependencies can be specified and will be installed with pip -->
          <option name="dep-module" value="mobly" />
        </target_preparer>
    </device>
    <device name="device2">
        <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
            <option name="test-file-name" value="wifi_aware_snippet.apk" />
        </target_preparer>
        <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
            <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
            <option name="run-command" value="wm dismiss-keyguard" />
        </target_preparer>
    </device>

    <test class="com.android.tradefed.testtype.mobly.MoblyBinaryHostTest">
      <!-- The mobly-par-file-name should match the module name -->
      <option name="mobly-par-file-name" value="CtsWifiAwareTestCases" />
      <!-- Timeout limit in milliseconds for all test cases of the python binary -->
      <option name="mobly-test-timeout" value="60000" />
    </test>
</configuration>

请注意:

  • 此示例测试依赖于 Mobly。可以为PythonVirtualenvPreparer指定任何依赖项,并将使用 pip 安装。
  • MoblyBinaryHostTest 的MoblyBinaryHostTest mobly-par-file-name必须与 Android.bp 中的模块名称匹配。
  • 请为测试指定一个mobly-test-timeout 。它以毫秒为单位,适用于完整的 python 二进制执行(所有测试用例一起)。这是为了避免测试用例在某些问题的情况下永远挂起。
  • 每个device标签可以在每个设备上包含不同的设置,Mobly 配置将按照 XML 中指定的顺序接收它们。

与片段 apk 安装相关:

  • 由于与 Coverage 团队的对话,初始 POC 已更新为通过 target_preparer 安装片段 apk:为了确保不会过早删除覆盖率测量,通过 Harness 而不是 Python 二进制文件中的测试代码卸载在时间方面提供了更好的保证。

第 5 步:在本地运行测试:atest

目前,多设备测试仅在物理设备上运行。在运行测试之前,请验证您的测试设备是否处于正确状态。命令adb devices应该报告您连接的设备列表。如果列表包含不用于测试的设备,请使用 -s 标志指定用于测试的设备。

对于 wifi 测试,请确保为设备启用了 wifi(恢复出厂设置后)。

您可以使用 atest 在本地运行测试:

$ atest CtsWifiAwareTestCases

您应该会在测试输出的摘要标题中看到使用的设备数量,例如Test executed with 2 device(s)

故障排除

如果由于以下原因在本地运行时测试失败:

虚拟环境错误

java.io.IOException: Cannot run program
"virtualenv": error=2, No such file or directory

请确保virtualenv在您的 PATH 中。将“~/.local/bin”添加到 PATH 应该可以解决它。如果未安装 virtualenv,请遵循:https://virtualenv.pypa.io/en/latest/installation.html

预计至少得到 2 个控制器对象,得到 1 个

测试模块是多设备或单设备,没有混合模块。如果您尝试在没有多个设备的情况下运行多设备模块,您将看到此错误:

Expected to get at least 2 controller objects, got 1

在多设备模式下执行模块将解决该问题。

对于 CTS:您可以使用分片来触发它(例如:--shard-count 2)或run cts-multidevces