Testes no Front-end: Escrevendo seu primeiro teste
Tags: testing, react, javascript, frontend
Published: 2023-03-02 15:30:00

No último artigo eu falei um pouco sobre testes no front-end, os motivos de testar suas aplicações, tipos de testes e principais ferramentas para isso. 

Neste artigo iremos escrever nosso primeiro teste para um componente de uma aplicação React. Vamos lá!

## Criando o componente

Suponha que precisamos testar o seguinte componente React chamado "Counter", que exibe um contador que é incrementado sempre que um botão é clicado:

```jsx
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  function incrementCount() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Contador: {count}</h1>
      <button onClick={incrementCount}>Incrementar</button>
    </div>
  );
}

export default Counter;
```
Esse componente não recebe nenhuma _prop_, ele tem apenas um estado, o contador (count) que é incrementado sempre que o botão "Incrementar" é clicado. 

Perfeito! Então vamos criar um teste para este componente.

## Testando o componente `<Counter />`

Para testar componentes React eu vou usar o [Jest](https://jestjs.io/pt-BR/) e o [Testing Library](https://testing-library.com/). O Jest é bem fácil de usar e servirá para fazermos asserções sobre nosso código, enquanto que o Testing Library serve para para facilitar a renderização dos componentes e a interação com eles. 

Se você criou sua aplicação React com o Create React App (CRA) é provável quee já tenha tanto o jest como os recursos do React Testing Library no seu projeto. Se não, se você usou o Vite por exemplo, pode ser que precise instalar essas dependências. Para instalar é bem simples, é só digitar no seu terminal 

```bash
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
``` 
Ambiente preparado, então vamos ao teste. 

Vamos criar um arquivo de teste para o componente Counter, com o nome `Counter.test.js`:

```js
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom/extend-expect';
import Counter from './Counter';

describe('Counter', () => {
  it('Deve renderizar o contador sem erros', () => {
    render(<Counter />);
    const textoContador = screen.getByText('Contador: 0');
    expect(textoContador).toBeInTheDocument();
  });

  it('Deve incrementar o contador quando o botão é clicado', () => {
    render(<Counter />);
    const botaoIncrementar = screen.getByText('Incrementar');
    const novoTextoContador = screen.getByText('Contador: 1');
    userEvent.click(botaoIncrementar);
    expect(novoTextoContador).toBeInTheDocument();
  });
});
```
Tá, mas o que significa cada linha deste teste? Vou explicar.

Primeiro precisamos fazer as importações dos utilitários que iremos precisar. Para renderizar nosso componente importamos o `render`, para observar o que foi renderizado utilizamos `screen` e para fazer consultas aos elementos desse componente utilizamos o `getByText()`. Não se preocupe com essas funções e utilitários agora, irei  trazer explicações mais detalhadas sobre cada um em outros artigos.

Para agrupar e organizar melhor os testes deste componente, eu utilizo o `describe` e dou uma descrição que nada mais é que o nome do componente, mas você pode fazer descrições mais detalhadas. 

O teste em si mesmo, só começa quando declaramos ele, com o `it()`. O `it` recebe dois parâmetros, que é a descrição do cenário de teste e uma função que executará o teste. 

Como boa prática, eu gosto de seguir uma ordem ao escrever um cenário de teste.

1. Renderizo o componente que estou testando com o render;
2. Faço uma consulta a um elemento usando o `screen` e uma _query_ de consulta, neste caso o `getByText()`;
3. Faço uma asserção, que é a comparação entre o que eu espero e o que eu recebo no meu teste;

Neste primeiro teste eu tenho dois cenários: 

- O primeiro verifica se o componente `<Counter />` é renderizado sem erros e se o contador é iniciado com o valor 0.
- O segundo simula um clique no botão "Incrementar" e verifica se o contador é incrementado corretamente.

O clique no botão é realizado utilzando o utilitário `userEvent`, que possui uma grande quantidade de eventos que simulam interações com a página, como digitar em campos de texto, selecionar opções em um select, etc.

Como outra boa prática eu gosto de salvar o que é retornado das consultas em variáveis e dar nome à elas que sejam significativos. Por exemplo, eu  usei o _textoContador_ para receber o que foi retornado de resultado da minha consulta a este elemento. E chamei de _botaoIncrementar_ o botão que obtemos ao fazer a consulta pelo seu texto também. 

Você pode perceber que ao fazer isso, fica bem mais simples de ler o teste, por exemplo, nesta asserção:

```js
expect(textoContador).toBeInTheDocument();
```
Ao ler eu claramente sei o que esse teste faz, que é: "Espero que o texto do contador esteja no documento". 

## Executando os testes

Para executar os testes de sua aplicação é bem simples, é só digitar em um terminal 

```bash
npm test
```
Este script vem como padrão ao iniciar a aplicação com o CRA.

---

E prontinho! Em menos de cinco minutos você escreveu o que chamamos de **testes de unidade** para um componente React. Este tipo de teste é simples, onde estamos _testando uma unidade_, no caso um componente, que é uma função, e como esse componente tem sua própria responsabilidade, que é renderizar o contador e incrementá-lo ao clicar em um botão, ele pode ser facilmente testado com testes esse. 

Dependendo do projeto, pode ser necessário escrever testes mais complexos e abrangentes para garantir a qualidade do código. 

Maneiro né? Se está gostando dessa série de artigos sobre testes no Front-end comenta aí o que tem achado e se esse conteúdo tem te ajudade de alguma forma!

Até a próxima!