Iniciando com Detox framework — 4/4

Utilize detox para saúde dos seus testes

Jhonatas Matos
Quia Digital
8 min readOct 9, 2020

--

Seguindo com a série de artigos para ajudar na configuração e execucação do detox, apresentamos a última parte onde iremos aprender a escrever nossos testes com detox e como o detox funciona.

Para Escrever o Primeiro Teste

Este tutorial supõe que o Detox já tenha sido instalado com sucesso em um projeto funcional com React Native.

➢ Sugestão: Veja também este tutorial incrível em vídeo no Medium feito pelo @bogomolnyelad.

1° Passo: Prepare um arquivo do Javascript para manter seu cenário (spec.)

Cada cenário de teste do Detox é, geralmente, colocado em seu próprio arquivo do Javascript. Se seguir o tutorial de instalação, estes arquivos estão localizados dentro do /e2e/*.spec.js sob o seu projeto raiz do React Native.

Sinta-se livre para colocar estes arquivos onde preferir, esta estrutura do diretório é apenas uma recomendação.

Caso esteja usando o Mocha como seu executor de testes, estes arquivos serão executados um por um durante os testes.

Após seguir o tutorial de instalação, o firstTest.spec.js já deve estar disponível inicialmente como um placeholder.

2° Passo: Decida como resetar seu aplicativo para o começo do cenário

Para começar o cenário de um aplicativo previsível declare e resete o estado de todos os cenários passados que podem estar ativos, é normal começar o cenário reiniciando o aplicativo.

A maneira a mais rápida de resetar é chamando await device.reloadReactNative(); .

Isso é equivalente a pressionar CMD+R na janela do simulador, ele reinicia o pacote React Native. Existem outras alternativas mais lentas, porém mais completas aqui.

Nosso cenário é feito de múltiplos casos de teste diferentes (cláusulas it()).

Geralmente procuramos resetar antes que cada um esteja funcionando. Isto pode ser realizado colocando a lógica do reset dentro de uma cláusula beforeEach().

3° Passo: Adicione testIDs ao seu aplicativo para ajudar a combinar elementos

A maioria dos casos de teste começam encontrando um elemento de UI na tela (que combina) e executando alguma interação do usuário nela (ação). Para ajudar a encontrar o elemento correto de UI, é recomendado marcá-lo de alguma maneira. A melhor prática é usar o testID de suporte para esta finalidade. Isso significa que modificaremos o código do aplicativo e adicionaremos estes suportes aos vários elementos.

Note que nem todos os componentes do React suportam essa propriedade. Entretanto, a maioria dos componentes nativos incorporados no React Native, como View, Text, TextInput, Switch, ScrollView têm suporte. Caso crie seus próprios componentes em composite, será necessário propagar manualmente este suporte ao componente nativo correto.

4° Passo: Combine um elemento e execute uma ação

Escolha um método para combinar com seu elemento, várias alternativas são documentadas aqui. É provável que o testID seja priorizado, o que significa que nosso código combinado vai se parecer com isso: element(by.id("MyUniqueId123").

Escolha uma ação para executar no elemento, várias alternativas são documentadas aqui. Se tivermos um botão, um tap, é provavelmente o que estamos procurando, resultando neste código:

5° Passo: Defina uma expectativa no resultado

Após efetuar a ação, o aplicativo provavelmente fará alguma coisa. O processo pode levar um tempo — por exemplo se estivermos logando, havería um pedido do servidor. A parte boa do detox é que não há preocupação com sincronização e quantas ações temporais são necessárias. Detox monitorará o aplicativo e continuará na linha seguinte em seu teste somente quando o aplicativo termina operações pendentes e se torna inativo.

A expectativa a mais natural é verificar se o algum elemento UI eventualmente apareceu na tela como resultado. Como antes, será necessário combinar ess elemento primeiro. Podemos continuar usando o testID para esta finalidade com o element(by.id("AnotherUniqueId456") .

As várias expectativas disponíveis são documentadas aqui. Para ter certeza de que um elemento é visível, teremos:

Note que o combinador de visibilidade se certifica que o elemento é visível na tela (pelo menos 75% dele para ser exato). Se aparecer sob o limite da tela (por exemplo, o usuário tem que scrolar a página para vê-lo), este combinador específico falhará.

6° Passo: Analisar e Repetir

Crie casos de teste mais complicados, combinando ações e expectativas uma após a outra. Explore o resto do API para ver o que é possível fazer em seus testes.

Adicione mais casos de teste em seu arquivo adicionando cláusulas it() . Crie cenários novos adicionando novos arquivos *.spec.js .

7° Passo: Execute os testes e certifique-se que eles funcionarão

Geralmente é feito executando o detox testno terminal. Se seu teste não estiver funcionando e não está claro o porquê, confira o tutorial para correção de erros.

Como prosseguir daqui? Leia sobre os vários workflows recomendados documentados pelo detox aqui. É esperado que encontre um workflow que auxilie em seu progresso, e complemente seu processo de desenvolvimento.

Como o Detox funciona

Detox é uma estrutura de teste end-to-end. Isso significa que ele executa seu aplicativo em um dispositivo/simulador real e interage como um usuário de verdade faria. Esse tipo de testes pode dar muita confiança para lançar seu aplicativo e ajudar a automatizar o processo manual de SQA. Caso venha de um cenário da web, é bastante parecido com o conceito do protractor.

Quando um teste de Detox é executado, existem duas partes diferentes funcionando lado a lado:

  • O aplicativo mobile em si: Geralmente executado em um simulador. Aparelhos reais serão suportados em breve. Uma estrutura nativa normal do aplicativo é instalada e executada no aparelho. O aplicativo geralmente é criado antes dos testes começarem.
  • Conjunto de testes: Operando em Node.js usando um executor de testes como Mocha. Os testes são normalmente escritos em JavaScript. Essa parte é executada fora do aplicativo e se comunica com outro no aparelho pela rede usando um websocket (HTTP). Como os testes são assíncronos por natureza (cada linha de teste requer acesso ao aplicativo e espera por uma resposta), então os testes dependem muito no async-await .

As duas partes estão quase sempre funcionando em processos separados na máquina. Também é possível executar as duas partes em máquinas diferentes. A comunicação entre as duas partes ocorre pela rede usando um websocket.

Na prática, para tornar a comunicação mais resiliente, ambas as partes são implementadas como clientes e se comunicam com um servidor Detox, que atua como proxy. Isso permite alguns comportamentos interessantes, como permitir que um lado se desconecte (durante a inicialização do simulador, por exemplo, ou a reinicialização do aplicativo), sem desconectar o outro lado e perder seu estado.

Como Detox Automaticamente Sincroniza Com Seu Aplicativo

Um dos principais recursos do Detox é sua capacidade de sincronizar automaticamente a execução do teste com seu aplicativo. O aspecto o mais irritante de testes end-to-end é a instabilidade — os testes às vezes falham sem que nada mude. A instabilidade ocorre porque os testes não são determinativos. Cada vez que um teste está sendo executado, as coisas acontecem em uma ordem ligeiramente diferente dentro do seu aplicativo.

Considere um cenário em que o aplicativo está fazendo várias solicitações de rede ao mesmo tempo. Qual é a ordem de execução? Depende de qual solicitação é concluída primeiro. É uma preocupação externa, que depende do congestionamento da rede e do quão ocupado o servidor está.

O método tradicional de lidar com a instabilidade é adicionar vários comandos de “sleep” ao longo do teste, na tentativa de forçar uma determinada ordem de execução. Essa é uma prática ruim fantasiada com valores mágicos frágeis que frequentemente mudam se a máquina que está executando os testes se torna mais rápida ou mais lenta.

O Detox elimina a instabilidade ao sincronizar automaticamente seus testes com o aplicativo. Um teste não pode continuar na linha seguinte se o programa estiver

ocupado. O teste recomeçará somente quando o software que está sendo executado se torna inativo. O Detox monitora seu aplicativo de perto para saber quando ele está ocioso. Ele rastreia diversas operações assíncronas e espera até que sejam concluídas. Isto inclui:

  • Acompanhar todas as solicitações de rede que estão em andamento e aguardar até que sejam concluídas;
  • Acompanhar as animações pendentes e esperar até que sejam concluídas;
  • Acompanhar os temporizadores (como setTimeout) e esperar até que expirem;
  • Acompanhar a ponte React Native, que transporta mensagens assíncronas;
  • Acompanhar o layout assíncrono do React Native e de processos paralelos;
  • Acompanhar o loop de eventos JavaScript que pode conter ações assíncronas pendentes.

Arquitetura

O diagrama de sequência abaixo mostra o esquema geral de comunicação entre os componentes no Detox.

Para entender melhor esse tópico é preciso dar uma olhada em um exemplo de ação detalhado. Os números na lista abaixo correspondem aos do diagrama.

Ação ( element.tap )

  1. element.tap() é iniciado no seu caso de teste.
  2. TapAction é iniciado em expect.js
  3. A instância TapAction é passada para invoke.js , onde é transformada em JSON. O JSON resultante se correlaciona mais com o código nativo do que com o código JS para melhor extensibilidade.
  4. JSON é enviado para o servidor Detox pelo Client.js
  5. O servidor Detox o encaminha para o teste em DetoxServer.js
  6. DetoxManager.m inicia o TestRunner.m . TestRunner.m usa o

DTXMethodInvocation.m para mapear a representação JSON dos comandos nativos no verdadeiro comando e o executa. (8)

NOTA: as imagens podem ser atualizadas com mermaid. Os arquivos podem ser encontrados em img-src.

Workflows

Existem múltiplas formas recomendadas de trabalhar com o Detox e fazer dele parte do seu processo de desenvolvimento. Escolha o melhor workflow para suas necessidades:

Executar Testes Locais na sua Máquina — Se seu aplicativo está pronto e não requer nenhum desenvolvimento ativo, é possível escrever os testes usando este workflow e executá-los localmente em sua máquina. Isso é conveniente para desenvolver seu conjunto de testes sem contribuir para o desenvolvimento ativo do seu aplicativo.

  • Desenvolver Seu Aplicativo Enquanto Escreve Testes — Se seu aplicativo requer desenvolvimento ativo, como adicionando campos testID para testes, este é um bom workflow. Ele permite trabalhar no aplicativo e no teste ao mesmo tempo.
  • Executando Testes em CI (como Travis) — Quando seu conjunto de testes está finalmente pronto, ele deve estar pronto para ser executado automaticamente em seu servidor de CI em todo git push. Isso vai alertar caso novas mudanças no aplicativo interrompam sua funcionalidade.
  • Depurar Aplicativos em Xcode Durante um Teste — Usuários avançados podem precisar de depurar seus aplicativos dentro do Xcode durante um teste do Detox. Isso é útil na maioria das vezes, quando está contribuindo para o próprio Detox.

--

--