O VTS é compatível com 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 módulos de teste.
Os requisitos de dispositivo, como número e tipos de dispositivos, são especificados na configuração do plano de teste. Por exemplo, você pode especificar um plano de teste que exige dois dispositivos Android com destinos de build do Sailfish.
Alocação de dispositivos
A infraestrutura de teste (geralmente o programador de testes) 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 do VTS são enviados e executados em todos os dispositivos alocados, a menos que haja uma instrução específica para não executar. 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
A biblioteca executa preparadores de teste para todos os dispositivos de que recebeu números de série. Os preparadores de destino podem ser de dispositivo único ou múltiplo:
- Preparadores de destino de dispositivo único (exemplo em
VtsDeviceInfoCollector):
- Só pode ser especificado na configuração do plano de teste com a lista de dispositivos necessária. As versões futuras vão permitir a configuração no nível do módulo.
- Receber 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 na configuração do módulo de teste
- Receber todos os números de série dos dispositivos
- Execute tarefas de preparação e limpeza em cada dispositivo ou em todos eles.
Módulos de teste
Os módulos de teste recebem uma lista de dispositivos depois que os preparadores de teste terminam de configurar o host/dispositivos. Um módulo de teste Python do lado do host é executado para cada módulo de teste multidispositivo. Os dispositivos Android alocados podem ser acessados nos 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 eficazes em vários dispositivos Android envolvem a comunicação entre os aparelhos 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 criar outros modelos.
Tipo 1: testes de HAL no lado do host
Os testes de HAL do lado do host podem usar drivers de HAL do VTS enviados aos dispositivos por padrão:
Neste cenário:
- A lógica de teste é executada no host.
- O script de teste do lado 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 agente no lado do host
Em vez de usar agentes VTS no dispositivo, um teste do lado do host também pode enviar o próprio agente (app ou binário) para cada dispositivo:
Neste cenário:
- A lógica de teste é executada no host.
- O app (ou binário) do agente é instalado em cada dispositivo.
- O script de teste do lado do host envia comandos para apps em cada dispositivo.
- O lado do host coordena as interações do dispositivo.
Por exemplo, os Testes do próximo bilhão de usuários no repositório VTS atual são testes do lado do host, baseados em apps e em vários dispositivos.
Tipo 3: testes de HIDL do lado do destino
Os testes HIDL de vários dispositivos do lado do destino 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:
Neste cenário:
- A lógica de teste é executada em dispositivos.
- O framework do lado do host fornece a identificação inicial do dispositivo.
- O binário de teste do lado de destino exige 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 controlados pelo 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 em Python do lado do host
Para detalhes e exemplos sobre preparadores de teste, consulte Preparadores de teste. 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')