Escreva um executor de teste Tradefed

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

Fundo

Se você estiver curioso sobre o lugar dos executores de teste na arquitetura Tradefed, consulte Estrutura de um executor de teste .

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

Mínimo: Implemente 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) .

Esse método é aquele invocado pelo arnês 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.

Relate os resultados do executor do teste

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

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

  • Relate uma lista adequada de todos os testes executados, quanto tempo levaram e se passaram individualmente, falharam ou alguns outros estados.
  • Métricas de relatório associadas aos testes, se aplicável, por exemplo, métricas de tempo de instalação.
  • Adequar-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 isso, relatar resultados estruturados é opcional; um executor de teste pode simplesmente querer avaliar o estado de toda a execução como PASSED ou FAILED sem quaisquer detalhes da execução real.

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

  • testRunStarted: Notifica o início de um grupo de casos de teste que estão relacionados entre si.
    • 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 nenhuma mudança de estado é considerado aprovado.
    • testEnded: Notifica o fim 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 pode 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 fim 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, garantir que testRunEnded seja chamado em caso de exceção usando uma cláusula finally .

Callbacks 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 . Isso é feito de propósito para manter as coisas próximas de algo básico sobre o qual os desenvolvedores geralmente têm conhecimento.

Logs de relatório do executor de teste

Se 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 forma:

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

Teste com um dispositivo

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

Os escritores de teste que desejam ir para a próxima etapa do teste de dispositivo 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 teste geralmente estão interessados ​​nessas 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

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

Para escrever um executor de teste que pode 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 dispositivo e suas informações de compilação associadas.

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

Testes cientes de suas configurações

Algumas implementações do executor 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 teste flexível

Os executores de teste 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 chicote e a infraestrutura maiores aproveitem esse controle fino e os usuários executem parcialmente o executor de teste 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 IFF se ele corresponder a um ou mais dos 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 devem ser executados, desde que não correspondam a nenhum dos filtros de exclusão.