Тестирование на нескольких устройствах

VTS поддерживает тесты, требующие взаимодействия между несколькими устройствами Android.

Архитектура

VTS использует фреймворк TradeFed для получения и передачи серийных номеров устройств в тестовые модули.

Рисунок 1. Серийные номера устройств пропускания СУДС.

Требования к устройствам, такие как количество и типы устройств, указываются в конфигурации плана тестирования. Например, вы можете указать план тестирования, требующий двух устройств Android с целевыми сборками Sailfish.

Распределение устройств

Тестовая инфраструктура (обычно планировщик тестов) выделяет доступные устройства, удовлетворяющие требованиям, указанным в конфигурации плана тестирования, фреймворку VTS. Выделенные устройства резервируются для плана тестирования, даже если тестовый модуль их не использует. Затем исполняемые файлы агента VTS отправляются на все выделенные устройства и запускаются на них (если не указано иное). Это гарантирует, что TCP-соединения для команд оболочки и RPC-вызовов HAL доступны для всех устройств в тестовом сценарии.

Составители тестов

Фреймворк запускает тестовые подготовительные модули для всех устройств, для которых получены серийные номера. Целевые подготовительные модули могут быть рассчитаны на одно или несколько устройств:

  • Подготовители целевых объектов для одного устройства (пример на 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. Тест на стороне хоста, основанный на агенте.

В этом сценарии:

  • Тестовая логика выполняется на хосте.
  • Приложение-агент (или двоичный файл) устанавливается на каждое устройство.
  • Тестовый скрипт на стороне хоста выдает команды приложениям на каждом устройстве.
  • Хостовая сторона координирует взаимодействие устройств.

Например, тесты Next Billion User в текущем репозитории 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 .

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')