Teste multidispositivo

O VTS oferece suporte a testes que exigem interação entre vários dispositivos Android.

Arquitetura

O VTS usa o framework TradeFed para receber e transmitir números de série de dispositivos para testar módulos.

Figura 1. VTS transmitindo números de série do dispositivo.

Os requisitos do dispositivo, como número e tipos, são especificados na configuração do plano de teste. Por exemplo, é possível especificar um plano de teste que exija dois dispositivos Android com destinos de build do Sailfish.

Alocação de dispositivos

A infraestrutura de teste (geralmente o programador de teste) aloca dispositivos disponíveis que atendem aos requisitos especificados na configuração do plano de teste para o framework VTS. Os dispositivos alocados são reservados para o plano de teste, mesmo que o módulo de teste não os esteja usando. Os binários do agente VTS são enviados e executados em todos os dispositivos alocados (a menos que sejam especificamente instruídos a não serem executados). Isso garante que as conexões TCP para comandos de shell e RPCs HAL estejam disponíveis para todos os dispositivos em um script de teste.

Preparadores de testes

O framework executa preparadores de teste para todos os dispositivos para os quais recebeu números de série. Os preparadores de destino podem ser de um ou vários dispositivos:

  • Preparadores de destino de um único dispositivo (exemplo em VtsDeviceInfoCollector):
    • Só pode ser especificado na configuração do plano de teste com a lista de dispositivos necessária (versões futuras vão permitir a configuração no nível do módulo).
    • Receba apenas um número de série do dispositivo.
    • Executar tarefas de preparação e limpeza em um dispositivo específico.
  • Preparadores de destino para vários dispositivos (exemplo em VtsPythonVirtualenvPreparer):
    • Pode ser especificado na configuração do plano de teste ou do módulo de teste.
    • Receber todos os números de série dos dispositivos
    • Execute tarefas de preparação e limpeza para cada dispositivo ou todos os dispositivos.

Módulos de teste

Os módulos de teste recebem uma lista de dispositivos depois que os preparadores de teste concluem a configuração do host/dispositivos. Um módulo de teste Python do host é executado para cada módulo de teste multidispositivo. Os dispositivos Android alocados podem ser acessados em módulos de teste do Python como uma lista de objetos AndroidDevice:

devices = self.android_devices
device1 = devices[0]
device1_serial = device1.serial

Todos os dispositivos alocados são reservados para o plano de teste, mesmo que um módulo de teste no plano esteja usando apenas um dispositivo.

Comunicação do dispositivo durante o teste

Testes multi-Android eficazes envolvem a comunicação entre dispositivos alocados. Ao desenvolver esses testes, você precisa determinar como estabelecer a comunicação entre os dispositivos alocados. As seções a seguir fornecem três exemplos de comunicação. No entanto, os desenvolvedores de testes podem projetar outros modelos.

Tipo 1: testes HAL do lado do host

Os testes HAL do lado do host podem usar drivers HAL do VTS que são enviados aos dispositivos por padrão:

Figura 2. Teste HAL no lado do host.

Nesse cenário:

  • A lógica de teste é executada no host.
  • O script de teste do host emite chamadas RPC para os drivers em cada dispositivo.
  • O lado do host coordena as interações do dispositivo.

Tipo 2: testes baseados em agentes no lado do host

Em vez de usar agentes VTS no dispositivo, um teste do host também pode enviar o próprio agente (app ou binário) para cada dispositivo:

Figura 3. Teste baseado em agente no lado do host.

Nesse cenário:

  • A lógica de teste é executada no host.
  • O app do agente (ou binário) é instalado em cada dispositivo.
  • O script de teste do host emite comandos para apps em cada dispositivo.
  • O lado do host coordena as interações do dispositivo.

Por exemplo, os testes Next Billion User no repositório atual do VTS são testes multidispositivos do lado do host e baseados em apps.

Tipo 3: testes HIDL do lado do destino

Os testes HIDL do lado do destino e de vários dispositivos colocam toda a lógica de teste em binários de teste do lado do dispositivo, o que exige que os testes sincronizem os dispositivos durante a execução do teste:

Figura 4. Teste HIDL baseado em destino.

Nesse cenário:

  • A lógica de teste é executada nos dispositivos.
  • O framework do host fornece a identificação inicial do dispositivo.
  • O binário de teste do lado do destino requer sincronização:
    • Mesmo binário de teste para todos os dispositivos.
    • Binários de teste diferentes para cada função.

Exemplo: plano de teste multidispositivo

Este exemplo especifica a configuração de dois dispositivos:

  • O dispositivo 1 inclui um provedor de build e um preparador de destino VtsDeviceInfoCollector.
  • O dispositivo 2 inclui um preparador FilePusher adicional que envia um grupo de arquivos relacionados ao host para o dispositivo.
<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>

Exemplo: script de teste Python do lado do host

Para detalhes e exemplos sobre os preparadores de testes, consulte Preparadores de testes. Para um exemplo completo de vários dispositivos do lado do host, consulte o codelab 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')