VTS 支持需要多个 Android 设备之间交互的测试。
架构
VTS 使用 TradeFed 框架来获取设备序列号并将其传递给测试模块。
设备要求(例如设备数量和设备类型)在测试计划配置中指定。例如,您可以指定一个需要两台具有 Sailfish 构建目标的 Android 设备的测试计划。
设备分配
测试基础架构(通常是测试调度程序)将满足测试计划配置中指定要求的可用设备分配给 VTS 框架。即使测试模块未使用已分配的设备,这些设备也会为测试计划保留。然后,VTS 代理二进制文件会被推送到所有已分配的设备并在其上运行(除非明确指示不运行)。这确保了 shell 命令和 HAL RPC 的 TCP 连接可用于测试脚本中的所有设备。
测试准备器
框架为收到序列号的所有设备运行测试准备器。目标准备器可以是单设备或多设备
- 单设备目标准备器(示例请参见 VtsDeviceInfoCollector)
- 只能在包含所需设备列表的测试计划配置中指定(未来版本将允许模块级别配置)。
- 仅接收一个设备序列号。
- 针对特定设备运行准备和清理任务。
- 多设备目标准备器(示例请参见 VtsPythonVirtualenvPreparer)
- 可以在测试计划配置或测试模块配置中指定
- 接收所有设备序列号
- 为每个设备或所有设备运行准备和清理任务。
测试模块
测试模块在测试准备器完成主机/设备设置后获取设备列表。一个主机端 Python 测试模块为每个多设备测试模块运行。已分配的 Android 设备可以从 Python 测试模块作为 AndroidDevice 对象列表访问
devices = self.android_devices device1 = devices[0] device1_serial = device1.serial
所有已分配的设备都为测试计划保留,即使计划中的测试模块仅使用一台设备也是如此。
测试期间的设备通信
有效的多 Android 测试涉及已分配设备之间的通信。在开发此类测试时,您必须确定如何在已分配的设备之间建立通信。以下部分提供了三个通信示例(但是,测试开发人员可以自由设计其他模型)。
类型 1:主机端 HAL 测试
主机端 HAL 测试可以使用默认推送到设备的 VTS HAL 驱动程序
在这种情况下
- 测试逻辑在主机上执行。
- 主机端测试脚本向每个设备上的驱动程序发出 RPC 调用。
- 主机端协调设备交互。
类型 2:主机端基于代理的测试
主机端测试也可以将自己的代理(应用或二进制文件)推送到每个设备,而不是使用设备上的 VTS 代理
在这种情况下
- 测试逻辑在主机上执行。
- 代理应用(或二进制文件)安装在每个设备上。
- 主机端测试脚本向每个设备上的应用发出命令。
- 主机端协调设备交互。
例如,当前 VTS 代码库中的Next Billion User 测试是主机端、基于应用的、多设备测试。
类型 3:目标端 HIDL 测试
目标端多设备 HIDL 测试将所有测试逻辑放在设备端测试二进制文件中,这要求测试在测试执行期间同步设备
在这种情况下
- 测试逻辑在设备上执行。
- 主机端框架提供初始设备识别。
- 目标端测试二进制文件需要同步
- 所有设备使用相同的测试二进制文件。
- 每个角色使用不同的测试二进制文件。
示例:多设备测试计划
此示例指定了两个设备的配置
- 设备 1 包括一个构建提供程序和
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')