Testando seu aplicativo nativo React (Parte 1)

(21 de dezembro de 2020)

Introdução

A maioria dos desenvolvedores acha o teste entediante e difícil de escrever, mas sabe de uma coisa? É preciso grande habilidade e experiência para saber como escrever testes significativos e sustentáveis. O conhecimento que você ganha ao aprender como testar seu código também mudará a maneira como você escreve código no desenvolvimento. Este artigo deve ajudá-lo a começar sua jornada de teste.

Diretrizes para melhores testes

Estas são algumas das diretrizes que aprendi depois de pesquisar como outros desenvolvedores estão testando seus códigos. Seguir essas diretrizes tornou mais fácil escrever e manter testes em toda a base de código.

1. Não teste a implementação do seu código

Para entender por que isso é importante, vejamos um cenário. Suponha que você escreveu uma função que recebe n como uma entrada e produz o resultado da adição do primeiro n números.

Vamos supor que você esteja testando getSumOfFirstN para n=2 ao afirmar que add é chamado de 2 times com os argumentos (0, 2) e (2, 1) respectivamente e a saída de getSumOfFirstN é 3.

Mais tarde, você descobrirá que existe uma maneira melhor de encontrar a soma do primeiro n números e reescrever o código acima.

Seu teste vai começar a falhar porque você não está mais chamando add

Este foi um exemplo simples, e isso é o que Sim, pode parecer contra-intuitivo, mas tenho visto muitos desenvolvedores fazendo exatamente esse tipo de teste em que o erro não é tão fácil de ver.

2. Não deixe seus testes se tornarem mais uma dívida tecnológica

Testar é importante, mas você também precisa entregar o código aos interessados ​​relevantes no prazo. Se sempre que você escreve um novo recurso ou modifica um existente, isso quebra seus antigos casos de teste ou você acaba gastando uma quantidade significativa de seu tempo alocado para consertar casos de teste antigos em vez de construir os recursos necessários, então, no final das contas, você acabará excluindo todos os testes antigos e o risco do projeto falhar na produção.

Seguir essas diretrizes deve ajudá-lo a garantir que seus testes sejam facilmente corrigíveis ou não quebrem quando sua base de código mudar.

3. Ao testar a IU, escreva os testes de uma forma que simule o comportamento real do usuário.

Suponha que você esteja testando se este botão foi renderizado e funcionando conforme o esperado ou não, primeiro pense em como o usuário iria encontrar e interagir com esse botão. Espero que eles vejam o texto “Enviar” e, em seguida, o pressionem, e isso é exatamente o que simularíamos. Em nosso caso de teste, primeiro pesquisaremos o texto “Enviar” e, em seguida, simularemos o evento “onPress” nele e, em seguida, declararemos tudo o que deveria fazer.

Em alguns casos, pode não ser fácil de identificar com exclusividade o componente que você deseja segmentar e, nesse caso, você pode usar testID prop, mas lembre-se de que você não estará simulando o comportamento completo do usuário se usar testID porque os usuários não visam componentes com base em seus testID.

Por que isso é importante? Por que devemos tentar simular o comportamento do usuário tanto quanto possível ao testar a IU? Isso ocorre porque, no final, será um humano que estará interagindo com sua IU e não um computador e se vir um “Olá” sendo renderizado em seu botão em vez de um “Enviar”, seu caso de teste deve estar falhando porque isso é algo que pode confundir o usuário final.

4. Funções puras são mais fáceis de testar do que funções impuras

Funções puras são funções que sempre darão a mesma saída para uma entrada correspondente, ou seja, se uma função pura bombear 2 para um 1, ele sempre faria isso, enquanto as funções impuras poderiam bombear 2 na primeira chamada e, em seguida, bombear 5 na segunda chamada.

É útil ter isso em mente ao escrever o código. Funções impuras podem se tornar mais fáceis de testar se o módulo que está introduzindo a “impureza” em tais funções for zombável.

5.Use fixtures como entrada e asserções em seus testes

Suponha que você tenha um objeto do tipo funcionário e várias funções operando nele, como uma função para capitalizar name, uma função para verificar se o funcionário é adulto ou não, etc.

Agora, suponha que você tome este objeto como entrada em todos os seus casos de teste.

Estes são seus dados fictícios ou seu “dispositivo elétrico”. Em seu primeiro caso de teste que testa se a função que coloca o nome em maiúscula está funcionando conforme o esperado ou não, você afirma que a saída é igual a { ...employee, name: employee.name.toUpperCase() } e em seu segundo caso de teste, você afirma se a função produz employee.age >= 18 ou não, e assim por diante.

Você deve estar se perguntando que vantagem obtemos usando os aparelhos de iluminação dessa maneira? A resposta é que você está tornando mais fácil para si mesmo corrigir testes rapidamente no futuro, escrevendo seus testes dessa maneira.

Por exemplo, E se quisermos adicionar outra propriedade maritalStatus no objeto funcionário, porque agora todos os nossos funcionários são obrigados a divulgar seu estado civil. Se em nosso primeiro caso de teste, declaramos que a saída é igual a { name: "KARTIK", age: 25, sex: "Male", children: 0 } em vez de { ...employee, name: employee.name.toUpperCase() }, nosso caso de teste será interrompido. Também será interrompido se alterarmos o valor de name para outro valor. Em outras palavras, nosso caso de teste não seria flexível e, portanto, teria uma chance maior de ser interrompido devido a alterações não relacionadas na base de código.

6. Escreva testes de unidade para componentes e funções utilitárias

Essas são partes do seu código que serão usadas por vários módulos. Portanto, eles precisam ser testados para todas as entradas / casos extremos possíveis, porque você não sabe como os outros módulos estarão usando essas funções / componentes. Portanto, eles não devem ter nenhum comportamento inesperado.

7. Escreva testes de integração para telas

É difícil escrever testes de unidade para telas porque geralmente, eles dependem de um grande número de componentes e outras bibliotecas de terceiros, como uma loja redux. Portanto, para escrever testes de unidade para telas, primeiro você terá que simular todas essas dependências, o que dá muito trabalho. É por isso que é melhor escrever testes de integração neste caso.

7. Escreva testes E2E para testar o código nativo

O código nativo não funciona em um ambiente de brincadeira. Então, para testá-lo, você terá que usar uma biblioteca como a Detox.

8. Sempre faça testes de instantâneo para telas e componentes

Se você fizer uma mudança de estilo em um componente que está sendo usado por várias outras telas / componentes, os testes de instantâneo para aqueles falharão até que você atualize os instantâneos. Isso o ajudará a entender quais outros módulos foram afetados pela mudança que você fez. Se você estiver trabalhando em equipe, isso realmente ajuda o revisor durante as revisões de RP a entender quais módulos foram afetados pela mudança específica que você fez no componente, porque as mudanças nos instantâneos desses módulos se refletem em seu RP.

Conclusão

Espero que você tenha achado este artigo útil e se estiver confuso com o que acabou de ler, não se preocupe. A segunda parte desta série será um tutorial sobre como configurar o ambiente de teste no React Native com exemplos de código de telas de teste, componentes e funções, seguindo as diretrizes que definimos nesta primeira parte.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *