多設備測試

VTS 支援需要多個 Android 裝置之間互動的測試。

建築學

VTS 使用 TradeFed 框架取得裝置序號並將其傳遞給測試模組。

圖 1.VTS傳遞設備序號。

設備要求(例如設備數量和設備類型)在測試計劃配置中指定。例如,您可以指定測試計劃,該計劃需要兩個具有 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 驅動程式:

圖 2.主機端 HAL 測試。

在這種情況下:

  • 測試邏輯在主機上執行。
  • 主機端測試腳本向每個裝置上的驅動程式發出 RPC 呼叫。
  • 主機端協調設備互動。

類型 2:基於主機端代理的測試

主機端測試還可以將其自己的代理程式(應用程式或二進位檔案)推送到每個設備,而不是在設備上使用 VTS 代理:

圖 3.主機端、基於代理的測試。

在這種情況下:

  • 測試邏輯在主機上執行。
  • 代理應用程式(或二進位)安裝在每個裝置上。
  • 主機端測試腳本向每個裝置上的應用程式發出命令。
  • 主機端協調設備互動。

例如,目前 VTS 儲存庫中的下一個十億用戶測試是主機端、基於應用程式的多裝置測試。

類型 3:目標端 HIDL 測試

目標端、多設備 HIDL 測試將所有測試邏輯放在設備端測試二進位檔案上,這需要測試在測試執行期間同步設備:

圖 4.基於目標的 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')