Prefer listening over reading? Press play and enjoy
Testes automatizados são scripts que verificam o funcionamento do sistema para garantir que ele funcione conforme o esperado. Existem diversos tipos de testes: unitários, de integração, end-to-end, de desempenho, de segurança, entre outros.
Neste artigo, vamos focar nos testes unitários e de integração, que são fundamentais na pirâmide de testes e amplamente utilizados no dia a dia.
Por que Escrever Testes Automatizados?
A principal razão para escrever testes é melhorar a qualidade e a robustez do código. Testes unitários verificam as menores partes do programa em isolamento, enquanto testes de integração garantem que diferentes partes do sistema funcionem bem em conjunto.
Em ambos os casos, fornecemos entradas específicas e verificamos se as saídas são as esperadas, focando no comportamento em vez da implementação, o que resulta em testes mais robustos.
Exemplo Prático: App de Cadastro de Usuários
Estes conceitos, à primeira vista parecem muito abstratos e difíceis de entender, por isso vamos olhar para o exemplo prático a seguir.
Aqui temos um app muito simples, que simula uma página de cadastro de usuários:
Os campos possuem algumas validações e caso sejam descumpridas, mensagens de erro são exibidas.
Com todas as validações ok, chamamos uma função assíncrona que aleatoriamente vai retornar erro:
Ou sucesso, com o nome do usuário criado:
Vamos agora para a estrutura de arquivos:
Na pasta hooks temos o hook que simula a criação de usuário. Dentro da feature Login, temos o componente a ser renderizado, estilos e os validadores de usuário e senha.
Com base nos conceitos abordados no início do artigo, qual parte do app você acha que devemos testar primeiro? Se pensou nos validadores, acertou!
Disclaimer (Ferramentas usadas)
Este artigo não tem como objetivo explicar a fundo as ferramentas envolvidas no teste e sim o entendimento dos conceitos, com a aplicação prática servindo para solidificar o entendimento. Dito isso, estamos usando a react-testing-library para renderizar e selecionar componentes da nossa UI e o jest como test runner.
Jest é uma ferramenta de teste desenvolvida pela Meta (Facebook), ideal para aplicações React, funciona executando testes em arquivos JavaScript. Ele detecta automaticamente os arquivos de teste, isola o código em execução, simula funções e módulos, e compara resultados esperados com os resultados reais, além de gerar relatórios de cobertura de código para identificar áreas não testadas.
A React Testing Library é uma ferramenta para testar componentes React. Ela foca em simular a interação do usuário e verificar se os componentes funcionam corretamente no contexto de uso real. A biblioteca permite renderizar componentes e interagir com eles.
Em linhas gerais usamos a React Testing Library para renderizar e interagir com os componentes e Jest para verificar se o estado atual do componente é o que estamos esperando.
Testes Unitários
Veja o validador de usuário, ele espera uma string user e retorna um booleano para informar se as condições foram atendidas e um array de mensagens de erro, que é preenchido de acordo com a regra que foi quebrada.
Conforme discutimos anteriormente, vamos fornecer entradas e esperar saídas. No teste abaixo fornecemos um usuário inválido por ter apenas 3 caracteres, neste caso isValid deve ser falso, o array de erro deve ter uma mensagem e ela tem que ser: usuário deve ter ao menos 4 caracteres.
Seguindo o mesmo raciocínio podemos construir os testes para os outros casos de usuário inválido.
Com todos os casos de erros cobertos por testes, falta apenas testar o caso de sucesso.
Para o validador de senha vamos seguir exatamente a mesma abordagem do teste anterior.
Fornecer entradas e conferir saídas
Com os testes unitários para os validadores concluídos, podemos começar os testes de integração na tela de Login.
Testes de integração
De acordo com o template, para cada validação que falhar, uma mensagem é exibida:
Vamos construir os testes para este comportamento. Usamos a react-testing-library para selecionar o campo de usuário, digitar um usuário inválido e clicar no botão cadastrar, a partir daí verificamos se as mensagens de erro estão visíveis na tela.
Basta seguir exatamente o mesmo raciocínio e temos os testes da validação de senha.
Caso o usuário erre e depois corrija os erros, deve-se apagar todos os erros.
Testamos isto procurando o container das mensagens de erro e verificando que não estejam no documento. Com a validação finalizada podemos começar a testar a "criação" do usuário.
Após o usuário pressionar cadastrar, com os dados corretos, temos três resultados possíveis:
- Carregando
- Sucesso
- Erro
Vamos adicionar testes para cada um deles.
Aqui temos comportamentos assíncronos e não queremos de forma nenhuma testar o que o método criar usuário faz e sim como nossa aplicação se comporta durante seus diferentes estados. Sendo assim vamos "mockar" a chamada nos status de loading sucesso e erro para conferir se estamos renderizando os elementos corretamente.
Como não nos interessa o que o hook create hook faz, vamos simular seu retorno no estado de loading e testar se a string "Loading …" está visível para o usuário.
Vamos seguir este conceito para a situação de sucesso, simulando o retorno de sucesso e conferindo se o banner aparece com o nome do usuário criado
E também para o caso de erro:
Com isso, testamos como as partes de nosso sistema funcionam de forma isolada e em conjunto.
Se você gostou deste artigo e achou as informações úteis, compartilhe com seus amigos e colegas nas redes sociais. Sua contribuição ajuda a disseminar conhecimento e pode fazer a diferença para outras pessoas. Obrigado por ler!