自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
多设备测试
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
VTS 支持需要在多部 Android 设备之间进行交互的测试。
架构
VTS 使用 TradeFed 框架获取设备序列号并将其传递给测试模块。

图 1. VTS 对设备序列号进行传递的过程。
设备要求(如设备数量和设备类型)在测试计划配置中指定。例如,您可以在测试计划中指定需要两部具有 Sailfish 编译目标的 Android 设备。
设备分配
测试基础架构(通常是测试调度程序)将满足测试计划配置中指定要求的可用设备分配给 VTS 框架。即使测试模块没有使用分配的设备,这些设备仍会保留用于测试计划。然后将 VTS 代理二进制文件推送到所有已分配设备上,并在设备上运行(除非有不要运行的特殊指示)。这可确保用于 shell 命令和 HAL RPC 的 TCP 连接可用于测试脚本中的所有设备。
测试准备器
框架会为所收到的序列号对应的所有设备运行测试准备器。目标准备器可以是单设备准备器或多设备准备器:
测试模块
在测试准备器设置完主机/设备后,测试模块会获取设备列表。系统会针对每个多设备测试模块运行一个主机端 Python 测试模块。分配的 Android 设备可以从 Python 测试模块(以 AndroidDevice 对象列表形式)访问:
devices = self.android_devices
device1 = devices[0]
device1_serial = device1.serial
即使测试计划中的测试模块仅使用了一部设备,所有已分配的设备都会保留用于测试计划。
测试期间的设备通信
有效的多 Android 设备测试需要在已分配设备之间进行通信。在开发此类测试时,您必须确定如何在已分配设备之间建立通信。以下部分提供了三个通信示例(但是,测试开发者可以自由设计其他模型)。
类型 1:主机端 HAL 测试
主机端 HAL 测试可以使用默认推送到设备的 VTS HAL 驱动程序:

图 2. 主机端 HAL 测试。
在这种情况下:
- 测试逻辑在主机上执行。
- 主机端测试脚本向每部设备上的驱动程序发出 RPC 调用。
- 主机端协调设备的交互。
类型 2:基于代理的主机端测试
除了在设备上使用 VTS 代理外,主机端测试还可以将自己的代理(应用或二进制文件)推送到每部设备:

图 3. 基于代理的主机端测试。
在这种情况下:
- 测试逻辑在主机上执行。
- 代理应用(或二进制文件)安装在每部设备上。
- 主机端测试脚本向每部设备上的应用发出命令。
- 主机端协调设备的交互。
例如,当前 VTS repo 中的下一批十亿用户测试是基于应用的主机端多设备测试。
类型 3:目标端 HIDL 测试
目标端、多设备 HIDL 测试将所有测试逻辑置于设备端测试二进制文件中,这要求测试在测试执行期间同步设备:

图 4. 基于目标的 HIDL 测试。
在这种情况下:
- 在设备上执行测试逻辑。
- 主机端框架提供初始设备标识。
- 目标端测试二进制文件需要同步:
- 所有设备使用的测试二进制文件相同。
- 每个角色使用的测试二进制文件不同。
示例:多设备测试计划
此示例为两部设备指定了配置:
- 设备 1 包括一个 build 提供程序和
VtsDeviceInfoCollector
目标准备器。
- 设备 2 包括一个额外的
FilePusher
准备器,可将一组主机驱动的相关文件推送至设备。
<configuration description="VTS Codelab Plan">
...
<device name="device1">
<build_provider class="com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider" />
<target_preparer class="com.android.tradefed.targetprep.VtsDeviceInfoCollector" />
</device>
<device name="device2" >
<build_provider class="com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider" />
<target_preparer class="com.android.tradefed.targetprep.VtsDeviceInfoCollector" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
<option name="push-group" value="HostDrivenTest.push" />
</target_preparer>
</device>
<option name="compatibility:include-filter" value="VtsCodelabHelloWorldMultiDeviceTest" />
</configuration>
示例:主机端 Python 测试脚本
有关测试准备器的详细信息和示例,请参阅测试准备器。有关完整的主机端多设备示例,请参阅 hello_world_multi codelab。
def setUpClass(self):
logging.info('number of device: %s', self.android_devices)
asserts.assertEqual(len(self.android_devices), 2, 'number of device is wrong.')
self.dut1 = self.android_devices[0]
self.dut2 = self.android_devices[1]
self.shell1 = self.dut1.shell
self.shell2 = self.dut2.shell
def testSerialNotEqual(self):
'''Checks serial number from two device not being equal.'''
command = 'getprop | grep ro.serial'
res1 = self.shell1.Execute(command)
res2 = self.shell2.Execute(command)
def getSerialFromShellOutput(output):
'''Get serial from getprop query'''
return output[const.STDOUT][0].strip().split(' ')[-1][1:-1]
serial1 = getSerialFromShellOutput(res1)
serial2 = getSerialFromShellOutput(res2)
logging.info('Serial number of device 1 shell output: %s', serial1)
logging.info('Serial number of device 2 shell output: %s', serial2)
asserts.assertNotEqual(serial1, serial2, 'serials from two devices should not be the same')
asserts.assertEqual(serial1, self.dut1.serial, 'serial got from device system property is different from allocated serial')
asserts.assertEqual(serial2, self.dut2.serial, 'serial got from device system property is different from allocated serial')
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-26。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# Multi-device testing\n\nVTS supports tests that require interaction between multiple Android\ndevices.\n\nArchitecture\n------------\n\nVTS uses the TradeFed framework to get and pass device serials to test\nmodules.\n\n**Figure 1.** VTS passing device serials.\n\nDevice requirements, such as number of devices and device types, are\nspecified in test plan configuration. For example, you can specify a test plan\nthat requires two Android devices with Sailfish build targets.\n\n### Device allocation\n\nThe test infrastructure (usually the test scheduler) allocates available\ndevices that satisfy the requirements specified in test plan configuration to\nthe VTS framework. Allocated devices are reserved for the test plan even if the\ntest module is not using them. VTS agent binaries are then pushed to and run on\nall allocated devices (unless specifically instructed not to run). This ensures\nthat TCP connections for shell commands and HAL RPCs are available for all\ndevices in a test script.\n\n### Test preparers\n\nThe framework runs test preparers for all devices for which it received\nserial numbers. Target preparers can be single or multi-device:\n\n- Single-device target preparers (example at [VtsDeviceInfoCollector](https://cs.android.com/android/platform/superproject/+/android-10.0.0_r47:test/vts/harnesses/tradefed/src/com/android/tradefed/targetprep/VtsDeviceInfoCollector.java)):\n - Can be specified only in test plan configuration with the required device list (future versions will allow module level configuration).\n - Receive only one device serial.\n - Run preparing and cleanup tasks against a specific device.\n- Multi-device target preparers (example at [VtsPythonVirtualenvPreparer](https://cs.android.com/android/platform/superproject/+/android-10.0.0_r47:test/vts/harnesses/tradefed/src/com/android/tradefed/targetprep/VtsPythonVirtualenvPreparer.java)):\n - Can be specified in test plan configuration or test module configuration\n - Receive all device serials\n - Run preparing and cleanup tasks for each device or all devices.\n\n### Test modules\n\nTest modules get a list of devices after the test preparers finish setting up\nthe host/devices. One host-side Python test module runs for each multi-device\ntest module. Allocated Android devices are accessible from Python test modules\nas a list of\n[AndroidDevice](https://android.googlesource.com/platform/test/vts/+/android16-release/utils/python/controllers/android_device.py#322)\nobjects: \n\n```\ndevices = self.android_devices\ndevice1 = devices[0]\ndevice1_serial = device1.serial\n```\n\nAll allocated devices are reserved for the test plan, even though a test\nmodule in the plan is only using one device.\n\nDevice communication during testing\n-----------------------------------\n\nEffective multi-Android tests involve communication between allocated\ndevices. When developing such tests, you must determine how to establish\ncommunication between the allocated devices. The following sections provide\nthree communication examples (however, test developers are free to design other\nmodels).\n\n### Type 1: Host-side HAL tests\n\nHost-side HAL tests can use VTS HAL drivers that are pushed to devices by\ndefault:\n\n**Figure 2.** Host-side HAL test.\n\nIn this scenario:\n\n- Test logic executes on the host.\n- Host-side test script issues RPC calls to the drivers on each device.\n- Host side coordinates device interactions.\n\n### Type 2: Host-side agent-based tests\n\nInstead of using VTS agents on device, a host-side test can also push its own\nagent (app or binary) to each device:\n\n**Figure 3.** Host-side, agent-based test.\n\nIn this scenario:\n\n- Test logic executes on the host.\n- Agent app (or binary) installs on each device.\n- Host-side test script issues commands to apps on each device.\n- Host side coordinates device interactions.\n\nFor example, the\n[Next\nBillion User tests](https://android.googlesource.com/platform/test/vts-testcase/nbu/+/android16-release) in current VTS repo are host-side, app-based,\nmulti-device tests.\n\n### Type 3: Target-side HIDL tests\n\nTarget-side, multi-device HIDL tests put all test logic on device-side test\nbinaries, which requires the tests to synchronize devices during test\nexecution:\n\n**Figure 4.**Target-based HIDL test.\n\nIn this scenario:\n\n- Test logic executes on devices.\n- Host-side framework provides initial device identification.\n- Target-side test binary requires synchronization:\n - Same test binary for all devices.\n - Different test binaries for each role.\n\nExample: Multi-device test plan\n-------------------------------\n\nThis example specifies the config for two devices:\n\n- Device 1 includes a build provider and `VtsDeviceInfoCollector` target preparer.\n- Device 2 includes an additional `FilePusher` preparer that pushes a group of host-driven related files to the device.\n\n```\n\u003cconfiguration description=\"VTS Codelab Plan\"\u003e\n ...\n\u003cdevice name=\"device1\"\u003e\n\u003cbuild_provider class=\"com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider\" /\u003e\n\u003ctarget_preparer class=\"com.android.tradefed.targetprep.VtsDeviceInfoCollector\" /\u003e\n\u003c/device\u003e\n\u003cdevice name=\"device2\" \u003e\n\u003cbuild_provider class=\"com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider\" /\u003e\n\u003ctarget_preparer class=\"com.android.tradefed.targetprep.VtsDeviceInfoCollector\" /\u003e\n\u003ctarget_preparer class=\"com.android.compatibility.common.tradefed.targetprep.VtsFilePusher\"\u003e\n\u003coption name=\"push-group\" value=\"HostDrivenTest.push\" /\u003e\n\u003c/target_preparer\u003e\n\u003c/device\u003e\n\u003coption name=\"compatibility:include-filter\" value=\"VtsCodelabHelloWorldMultiDeviceTest\" /\u003e\n\u003c/configuration\u003e\n```\n\nExample: Host-side Python test script\n-------------------------------------\n\nFor details and examples on test preparers, see\n[Test preparers](#test-preparers). For a complete host-side\nmulti-device example, refer to the\n[hello_world_multi\ncodelab](https://cs.android.com/android/platform/superproject/+/android-10.0.0_r47:test/vts/testcases/codelab/hello_world_multi/). \n\n```\ndef setUpClass(self):\nlogging.info('number of device: %s', self.android_devices)\nasserts.assertEqual(len(self.android_devices), 2, 'number of device is wrong.')\nself.dut1 = self.android_devices[0]\nself.dut2 = self.android_devices[1]\nself.shell1 = self.dut1.shell\nself.shell2 = self.dut2.shell\n\ndef testSerialNotEqual(self):\n'''Checks serial number from two device not being equal.'''\ncommand = 'getprop | grep ro.serial'\nres1 = self.shell1.Execute(command)\nres2 = self.shell2.Execute(command)\n\ndef getSerialFromShellOutput(output):\n'''Get serial from getprop query'''\nreturn output[const.STDOUT][0].strip().split(' ')[-1][1:-1]\nserial1 = getSerialFromShellOutput(res1)\nserial2 = getSerialFromShellOutput(res2)\n\nlogging.info('Serial number of device 1 shell output: %s', serial1)\nlogging.info('Serial number of device 2 shell output: %s', serial2)\nasserts.assertNotEqual(serial1, serial2, 'serials from two devices should not be the same')\nasserts.assertEqual(serial1, self.dut1.serial, 'serial got from device system property is different from allocated serial')\nasserts.assertEqual(serial2, self.dut2.serial, 'serial got from device system property is different from allocated serial')\n```"]]