Escreva um executor de teste Tradefed

Esta página descreve como escrever um novo executor de teste no Tradefed.

Fundo

Se você está curioso sobre o lugar dos executores de testes na arquitetura Tradefed, consulte Estrutura de um executor de testes .

Este não é um pré-requisito para escrever um novo executor de testes; executores de teste podem ser escritos isoladamente.

Mínimo: Implementar a interface

O mínimo para se qualificar como um executor de teste Tradefed é implementar a interface IRemoteTest e mais especificamente o método run(TestInformation testInfo, ITestInvocationListener listener) .

Este método é aquele invocado pelo chicote ao usar o executor de teste, semelhante a um Java Runnable.

Cada parte desse método é considerada parte da execução do executor de teste.

Relatar resultados do executor de teste

O método run na interface base dá acesso a um objeto ouvinte do tipo ITestInvocationListener . Este objeto é a chave para relatar resultados estruturados do executor de testes para o equipamento.

Ao relatar resultados estruturados, um executor de teste tem as seguintes propriedades:

  • Relate uma lista adequada de todos os testes realizados, quanto tempo demoraram e se foram aprovados, reprovados individualmente ou em algum outro estado.
  • Relate métricas associadas aos testes, se aplicável, por exemplo, métricas de tempo de instalação.
  • Adapte-se à maioria das ferramentas de infraestrutura, por exemplo, exibir resultados e métricas, etc.
  • Geralmente mais fácil de depurar, pois há um rastreamento mais granular da execução.

Dito isto, reportar resultados estruturados é opcional; um executor de teste pode simplesmente querer avaliar o estado de toda a execução como PASSADO ou FALHADO sem quaisquer detalhes da execução real.

Os seguintes eventos podem ser chamados no ouvinte para notificar o equipamento sobre o progresso atual das execuções:

  • testRunStarted: Notifica o início de um grupo de casos de teste relacionados.
    • testStarted: Notifica o início do início de um caso de teste.
    • testFailed/testIgnored: Notifica a mudança de estado do caso de teste em andamento. Um caso de teste sem qualquer mudança de estado é considerado aprovado.
    • testEnded: Notifica o final do caso de teste.
  • testRunFailed: Notifica que o status geral da execução do grupo de casos de teste é uma falha. Uma execução de teste pode ser aprovada ou reprovada , independentemente dos resultados dos casos de teste , dependendo do que a execução esperava. Por exemplo, um binário executando vários casos de teste poderia relatar todos os casos de teste aprovados , mas com um código de saída de erro (por qualquer motivo: arquivos vazados, etc.).
  • testRunEnded: Notifica o final do grupo de casos de teste.

Manter e garantir a ordem adequada dos retornos de chamada é responsabilidade do implementador do executor de teste, por exemplo, garantindo que testRunEnded seja chamado em caso de exceção usando uma cláusula finally .

Retornos de chamada de casos de teste ( testStarted , testEnded , etc.) são opcionais. Uma execução de teste pode ocorrer sem nenhum caso de teste.

Você pode notar que esta estrutura de eventos é inspirada na estrutura JUnit típica . O propósito é manter as coisas próximas de algo básico sobre o qual os desenvolvedores geralmente têm conhecimento.

Relatar logs do executor de teste

Se você estiver escrevendo sua própria classe ou executor de teste Tradefed, você implementará IRemoteTest e obterá um ITestInvocationListener por meio do método run() . Este ouvinte pode ser usado para registrar arquivos da seguinte maneira:

    listener.testLog(String dataName, LogDataType type_of_data, InputStreamSource data);

Teste com um dispositivo

A interface mínima acima permite executar testes muito simples, isolados e que não requerem nenhum recurso específico, por exemplo testes de unidade Java.

Os redatores de testes que desejam passar para a próxima etapa do teste de dispositivos precisarão das seguintes interfaces:

  • IDeviceTest permite receber o objeto ITestDevice que representa o dispositivo em teste e fornece a API para interagir com ele.
  • IBuildReceiver permite que o teste obtenha o objeto IBuildInfo criado na etapa do provedor de construção contendo todas as informações e artefatos relacionados à configuração do teste.

Os executores de testes geralmente se interessam por essas interfaces para obter artefatos relacionados à execução, por exemplo, arquivos extras, e obter o dispositivo em teste que será alvo durante a execução.

Teste com vários dispositivos

Tradefed suporta a execução de testes em vários dispositivos ao mesmo tempo. Isso é útil ao testar componentes que exigem interação externa, como o emparelhamento de um telefone e um relógio.

Para escrever um executor de teste que possa usar vários dispositivos, você precisará implementar o IMultiDeviceTest , que permitirá receber um mapa de ITestDevice para IBuildInfo que contém a lista completa de representações de dispositivos e suas informações de construção associadas.

O setter da interface sempre será chamado antes do método run , portanto é seguro assumir que a estrutura estará disponível quando run for chamado.

Testes cientes de suas configurações

Algumas implementações de executores de teste podem precisar de informações sobre a configuração geral para funcionar corretamente, por exemplo, alguns metadados sobre a invocação ou qual target_preparer foi executado antes, etc.

Para conseguir isso, um executor de teste pode acessar o objeto IConfiguration do qual faz parte e no qual é executado. Consulte a descrição do objeto de configuração para obter mais detalhes.

Para a implementação do executor de teste, você precisará implementar o IConfigurationReceiver para receber o objeto IConfiguration .

Executor de testes flexível

Os executores de testes podem fornecer uma maneira flexível de executar seus testes se tiverem um controle granular sobre eles, por exemplo, um executor de testes JUnit pode executar individualmente cada teste de unidade.

Isso permite que o equipamento e a infraestrutura maiores aproveitem esse controle preciso e que os usuários executem parcialmente o executor de testes por meio de filtragem .

O suporte à filtragem está descrito na interface ITestFilterReceiver , que permite receber conjuntos de filtros de include e exclude para os testes que devem ou não ser executados.

Nossa convenção é que um teste será executado se corresponder a um ou mais filtros de inclusão E não corresponder a nenhum dos filtros de exclusão. Se nenhum filtro de inclusão for fornecido, todos os testes deverão ser executados, desde que não correspondam a nenhum dos filtros de exclusão.