Esta página descreve como escrever um novo test runner no Tradefed.
Contexto
Se você tem dúvidas sobre o lugar dos executores de teste na arquitetura do Tradefed, consulte Estrutura de um executor de teste.
Isso não é um pré-requisito para criar um novo executor de testes. Os executores de testes podem ser criados de forma isolada.
Mínimo básico: implementar a interface
O mínimo para se qualificar como executor de testes do Tradefed é implementar a
Interface IRemoteTest (link em inglês)
e, mais especificamente, o método run(TestInformation testInfo, ITestInvocationListener listener)
.
Esse método é o invocado pelo harness ao usar o test runner, semelhante a um Runnable Java.
Cada parte desse método é considerada parte da execução do gerenciador de testes.
Relatar resultados do executor de teste
O método run
na interface base dá acesso a um objeto listener de
digite ITestInvocationListener
. Esse objeto é a chave para informar resultados estruturados
do executor de testes para o harness.
Ao relatar resultados estruturados, um executor de testes tem as seguintes propriedades:
- Informe uma lista adequada de todos os testes executados, quanto tempo eles levaram e se eles foram aprovados, reprovados ou tiveram algum outro estado.
- Métricas de relatórios associadas aos testes, se aplicável, por exemplo métricas de tempo de instalação.
- Se encaixa na maioria das ferramentas de infraestrutura, por exemplo, métricas e resultados de exibição.
- Geralmente, é mais fácil depurar, já que há um rastro mais granular da execução.
No entanto, o relatório de resultados estruturados é opcional. Um executor de teste pode simplesmente avaliar o estado de toda a execução como APROVADO ou REPROVADO sem nenhum detalhe da execução real.
Os eventos a seguir podem ser chamados no listener para notificar o arcabouço do 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 alteração de estado do caso de teste. em andamento. Um caso de teste sem nenhuma 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 estava esperando. Por exemplo, um binário que executa vários casos de teste poderia relatar todos os casos de teste aprovados, mas com um código de saída de erro (para qualquer motivos: arquivos vazados etc.).
- testRunEnded: notifica o final do grupo de casos de teste.
Manter e garantir a ordem adequada dos callbacks é
responsabilidade do implementador do executor de teste. Por exemplo, garantir que
testRunEnded
seja chamado em caso de exceção usando uma cláusula finally
.
Os callbacks de casos de teste (testStarted
, testEnded
etc.) são opcionais. Um teste
pode ocorrer sem nenhum caso de teste.
Você pode notar que essa estrutura de eventos é inspirada estrutura JUnit típica. Isso é proposital para manter as coisas próximas a algo básico que os desenvolvedores geralmente conhecem.
Gerar registros do executor de teste
Se você estiver escrevendo sua própria classe ou executor de teste Tradefed, vai implementar
IRemoteTest
e receber um ITestInvocationListener
pelo método run()
. Este listener
pode ser usada para registrar arquivos da seguinte forma:
listener.testLog(String dataName, LogDataType type_of_data, InputStreamSource data);
Testar com um dispositivo
A interface mínima acima permite executar testes muito simples que são isolados e não exigem recursos específicos, como testes de unidade do Java.
Os autores de testes que quiserem passar para a próxima etapa do teste de dispositivo vão precisar 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 receba o objeto
IBuildInfo
criado na etapa do provedor de build que contém todas as informações e artefatos relacionados à configuração do teste.
Os executores de teste geralmente têm interesse nessas interfaces para receber artefatos relacionados à execução, por exemplo, arquivos extras, e receber o dispositivo em teste que será direcionado durante a execução.
Testar com vários dispositivos
O Tradefed oferece suporte para a execução de testes em vários dispositivos ao mesmo tempo. Isso é útil ao testar componentes que exigem uma interação externa, como um emparelhamento de smartphone e relógio.
Para programar um executor de testes que possa usar vários dispositivos, você precisará
para implementar
IMultiDeviceTest (link em inglês),
que permite receber um mapa de ITestDevice
para IBuildInfo
que contenha
a lista completa de representações de dispositivos e as informações de versão associadas a elas.
O setter da interface sempre será chamado antes do método run
. Portanto,
é seguro presumir que a estrutura estará disponível quando run
for chamado.
Testes cientes das próprias configurações
Algumas implementações de 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 fazer isso, um executor de teste pode acessar o objeto IConfiguration
do qual ele faz parte e em que é executado. Consulte a
objeto de configuração
para mais detalhes.
Para a implementação do executor de testes, será necessário implementar a propriedade
IConfigurationReceiver (em inglês)
para receber o objeto IConfiguration
.
Executor de testes flexível
Os executores de testes podem oferecer uma maneira flexível de executar os testes se tiverem um controle granular sobre eles. Por exemplo, um executor de testes JUnit pode realizar executar cada teste de unidade.
Isso permite que o arcabouço e a infraestrutura maiores aproveitem esse controle refinado e os usuários executarem parcialmente o executor de testes por meio de filtragem.
O suporte à filtragem é descrito nas
Interface ITestFilterReceiver,
que permite receber conjuntos de filtros include
e exclude
para os testes.
que deve ou não ser executado.
Nossa convenção é que um teste será executado se corresponder a um ou mais dos filtros de inclusão E não corresponder a nenhum dos filtros de exclusão. Se não forem incluídos são fornecidos, todos os testes devem ser executados, desde que não correspondam a nenhum os filtros de exclusão.