Por que testar minha aplicação?

Por que testar minha aplicação?

De início pode parecer estranha a ideia de escrever um código que irá testar o código que acabou de escrever, por isso, muitos programadores costumam deixar os testes de lado. Contudo, ao criar testes automatizados para a aplicação, fica muito mais fácil garantir que ela está funcionando conforme o planejado, já que, agora com um único comando no terminal será possível testar todo o programa.

Dentro do mercado de trabalho, saber sobre testes é um grande diferencial e é algo essencial para o desenvolvimento do código. Quando temos testes em nosso produto, podemos identificar erros durante e após o desenvolvimento, garantir o funcionamento das funcionalidades do usuário e assegurar a qualidade do software. Ou seja, se todo mundo testar as suas criações, ninguém mais precisará testar.

Entendemos que todos, desde os desenvolvedores, até os analistas de testes, são responsáveis por testar a aplicação. Assim sendo, como começamos a testar? Nos próximos tópicos entenderemos os testes unitários, testes de integração e testes de ponta a ponta.

Testes unitários


São testes para partes específicas do código, como uma função ou um componente. Os testes unitários são importantes, pois eles são mais precisos. Quando ocorre um erro, sabemos exatamente em qual função aconteceu. Além disso, é o teste que garante que nenhuma função está com bugs. Ainda assim, apesar de os testes unitários serem os testes mais importantes, não testam as conexões entre componentes e não testam a atividade do usuário, algo que veremos a seguir.

Testes de integração

Nos testes de integração usamos os testes unitários para testar a conexão entre dois ou mais componentes. É um teste importante para se ter certeza que a comunicação entre as funções está funcionando corretamente.

Testes de ponta a ponta


Quando falamos de testes de ponta a ponta, no desenvolvimento estamos falando sobre simular as atividades do usuário para assegurar o funcionamento da aplicação do ponto de vista dele. É um teste muito importante, porém por testar o funcionamento do software “inteiro” muitos acabam utilizando somente essa abordagem. Isso tem como consequência um produto de pouca confiabilidade e também dificulta a manutenção do código.

Agora que passamos pelos conceitos iniciais de testes, estamos quase prontos para partir para os testes em código. Mas por qual tipo de teste começar?


Qual teste devo escolher?


Uma empresa, ao construir um computador, inicialmente testa as peças individuais, depois a comunicação entre as peças e por último ligam o computador e testam a atividade do usuário. Consequentemente, começamos a testar nossos componentes menores usando os testes unitários, em seguida os de integração e então, os de ponta a ponta.

Os testes unitários devem cobrir a maior parte da aplicação, sendo, em um bom código de teste cerca de 60-70% do seu conteúdo, enquanto os de integração cerca de 15-20% e o resto em testes de ponta a ponta.

Dessa maneira, finalmente entendemos quais devem ser as prioridades e em como dividir e organizar os testes dentro dos conceitos explicados anteriormente. Entraremos em exemplos mostrando na prática como começar a usar o ambiente Jest e, em seguida, como utilizar a React Testing Library.

Como começar a usar o framework Jest


Antes de partirmos para o React Testing Library, usaremos o Jest em um ambiente mais simples, usando somente o JavaScript Vanilla. Caso queira fazer como o exemplo, siga o passo a passo a seguir:

1) Crie um diretório para o projeto.

mkdir my_first_jest_project
cd my_first_jest_project

2) Criamos o package.json para instalar as dependências.

npm init -y

3) Instalamos o Jest

npm i –save-dev jest

4) Por fim, alteramos o conteúdo do arquivo package.json.

Dentro da propriedade “scripts” alteramos a propriedade “test”:

/package.json

Finalmente temos o setup inicial de testes. Após seguir os passos anteriores, criaremos o arquivo de testes.

Primeiro arquivo de testes RTL


A maneira mais segura de desenvolver uma aplicação é com o TDD (Desenvolvimento Orientado A Testes), ideia que consiste em primeiro criar os testes e, em seguida, a função ou componente.

Para fins de exemplo criaremos uma função que procura pelo número de id entre os empregados de uma empresa, essas informações estão em um Array. Cada empregado terá suas informações separadas em um Objeto.

Antes de criar a função criaremos o teste para ela:

/firstTest.test.js

Primeiro importamos o expect da biblioteca Jest, função que efetivamente irá testar nossos retornos.

Após isso, criamos o “describe”, função que recebe como primeiro parâmetro uma string e, como segundo, uma função anônima onde colocaremos as nossas funções de teste.

Já a função “test” tem uma estrutura idêntica ao describe e é responsável por isolar os escopos. Dentro da função test colocamos os expect, função que irá comparar o retorno da função “findEmployeeById” com a constante “employeeResult”.

Agora que temos o teste da função, podemos começar a desenvolver a funcionalidade.

Nossa função recebe o “id” e procura por meio da HOF find o objeto que tem a propriedade id igual ao id enviado como parâmetro.

Como exportamos a função com module podemos importar a função para o ambiente de testes:

Agora para verificar o funcionamento do teste rodamos o comando:

npm test

Todos os testes devem passar.

Outro fato importante é saber que existem diversos comparadores diferentes do toStrictEqual, como o “toBe” ou o “toBeTruthy”. Recomenda-se estudar na própria documentação do Jest. Outros exemplos disso seriam:

Nesse momento entendemos o funcionamento básico dos testes e passaremos para um novo exemplo em React, nos próximos tópicos entenderemos melhor sobre como testar a sua aplicação na prática.

Como usar o React Testing Library


React Testing Library é uma biblioteca leve que possui ótimas utilidades para testes. É um ambiente no qual podemos testar funções e a interação do usuário com a página. Assim sendo, começaremos o nosso exemplo.

Usando o create-react-app já teremos todas as configurações iniciais para começar a testar.

npx create-react-app first-time-with-rtl

cd first-time-with-rtl

Agora que temos o nosso setup do RTL, criaremos uma aplicação simples que pode buscar um funcionário específico ou pegar todos os funcionários. Normalmente, ao criar uma aplicação, começaríamos por testes, porém, para fins de entendimento começaremos por seu funcionamento.

Para iniciar crie o diretório utils dentro de /src:

/src/utils/getEmployees.js

Essa função será responsável por pegar as informações dos funcionários. A função está assíncrona para motivos de simulação, já que normalmente esse ato é realizado por um fetch.

Em seguida, criaremos o arquivo que terá as funções de procura de dados e alteração do estado global.

/src/utils/helpers.js

E, por último, antes dos testes, alteramos o arquivo App.js.

/src/App.js

Agora que temos os arquivos da nossa aplicação vamos começar pelos testes unitários, ou seja, será testado inicialmente os arquivos “getEmployees.js”  e “helpers.js”.

Crie o diretório /tests em /src e dentro dele o arquivo com o seguinte formato : nomeDoTeste.test.js

/src/tests/unitaryTests.test.js

Como podemos ver no exemplo acima, primeiro testamos a função procurando com um id existente, depois com um id não existente e depois testamos a função findAll. Rode o código a seguir no terminal para testar:

npm test

Tudo deve passar normalmente.

Posteriormente aos testes unitários podemos começar com os testes de interação do usuário.

Simulando o usuário com RTL


Crie um novo arquivo de testes no diretório /src/tests

/src/test/end-to-end.test.js

Inicialmente, no nosso novo arquivo, importamos algumas funções que usamos nos testes:

RTL render


Usamos a função render para renderizar um componente específico do React, não necessariamente precisa ser o App.js.

RTL screen


No nosso exemplo usamos a função screen para ver e interagir com determinado elemento da página, no nosso caso, os botões e o input. Mais especificamente começamos a selecionar os nossos elementos com as seguintes funções:

Como screen.getByRole funciona?


Ele é responsável por encontrar certo elemento na tela, caso não encontre o teste inteiro dá erro.

Como screen.queryByRole funciona?


O query é muito parecido com o get, porém, retorna null caso não encontre o elemento, ou seja, o teste não dá erro de crash. Para selecionar os elementos da página de maneira mais eficaz, baixe a extensão do Chrome: Testing Playground.

Como screen.findByRole funciona?


O findByRole espera um pouco mais para encontrar o elemento, e, por isso, precisa de await para garantir que a Promise foi esperada.

Isso posto, conseguimos desestruturar nossos testes de ponta a ponta e podemos começar a aplicar esses conceitos em outras aplicações. Recomendo estudar mais a fundo na documentação RTL o conceito de Mocks. Contudo, com isso já será o suficiente para aumentar a segurança no desenvolvimento do seu código.

Conclusão


A partir do momento que aplicamos os testes em qualquer projeto passamos segurança e confiabilidade para a estrutura do código. Além de ser essencial para a criação de qualquer produto, por ser um código, fica muito mais fácil identificar onde o bug está acontecendo e qual a provável causa.

Aprender testes é algo que todos os desenvolvedores devem praticar e muitos não o fazem por acreditar que o código não precisa Usar testes em seus projetos irá destacá-lo profissionalmente e facilitará a vida do desenvolvedor durante a manutenção e aplicação de features.

💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.