[pt-BR] Testes de Caso de Uso no React - #3
Published: 2022-02-07 14:39:38

Por muitas vezes ao pensar em testes do React, já pensamos direto em testes de detalhes de implementação. E já vimos por [aqui](https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-1-13f) o quando esse caminho pode acabar mascarando erros, ou atrapalhando a produtividade por serem muito frágeis.

Portanto, para aplicar os Testes de Caso de Uso no React, podemos sempre pensar em qual efeito observável que aquele código que quero testar tem para os nossos usuários como por exemplo, partes relacionadas a Métodos de ciclo de vida, Eventos dos elementos ou Estado interno de componentes.

Vamos ver aqui algumas técnicas práticas a pensar que vão para facilitar a implementação de testes em uma aplicação em React.

### O que será abordado:
- Como aplicar Testes de Caso de Uso no React?
- React Testing Library
- Conclusão

# Como aplicar Testes de Caso de Uso no React?

Provavelmente isso não é uma regra, mas podemos divir algumas partes do código do React pensando a que tipo de usuário ela se refere. Por exemplo:

**O usuário-final** vê e interage com aquilo que renderizamos, ou seja, tudo o que está dentro do render ou return.

**O usuário-desenvolvedor** vê e interage com os adereços que passamos para os componentes, como props, estados, contextos. 

Também temos elementos que precisamos testar e que são preocupantes para **ambos**, como por exemplo mudança na DOM, uma chamada HTTP, chamadas callback, ou outros tipo de efeitos colaterais que são observáveis como:

**Interações do usuário**: O usuário final é capaz de interagir com os elementos que o componente renderiza?

**Mudanças de props**: O que acontece quando o usuário-desenvolvedor re-renderiza o componente com novas props?

**Mudanças de contexto**: O que acontece quando o usuário desenvolvedor altera o contexto, resultando na rerenderização do seu componente? 

**Alterações de subscription**: O que acontece quando um emissor de evento relacionado a algum componente muda? (Como firebase, uma store do redux, uma rota, uma media query ou assinaturas baseadas em navegador, como status online)

# React Testing Library

Essa é uma ferramenta criada exclusivamente com o objetivo de escrever testes para manutenção de componentes React de forma que evite testar detalhes de implementação e manter a aplicação sustentável a longo prazo.

Vamos ver um exemplo de teste utilizando o React Testing Library, utilizando o mesmo exemplo do accordion que usamos na [parte 1](https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-1-13f), só que vamos reescrevê-lo em functional component com hooks:

```js
// accordion.js
export default function Accordion({ items })  {
    const [openIndexes, setOpenIndex] = useState([0])

    return (
      <div>
        {items.map((item, index) => (
          <>
            <button onClick={() => setOpenIndex([index])}>
              {item.title}
            </button>

            {openIndexes.includes(index) ? (
              <AccordionContents>
                {item.contents}
              </AccordionContents>
            ) : null}
          </>
        ))}
      </div>
    )
}
```
E agora escrevemos o teste, pensando no comportamento observável do componente:

- "Pode abrir items do accordion e ver seus conteúdos"

```js
test('Pode abrir items do accordion e ver seus conteúdos', () => {
  const hats = {
     title: 'Chapéu Favorito',
     contents: 'Fedoras são legais'
  }
  const footware = {
    title: 'Calçado Favorito',
    contents: 'Chinelos são os melhores',
  }

  render(<Accordion items={[ hats, footware  ]} />)
  
  expect(screen.getByText(hats.contents)).toBeInTheDocument()
  expect(screen.queryByText(footware.contents))
  .not.toBeInTheDocument()

  userEvent.click(screen.getByText(footware.title))

  expect(screen.getByText(footware.contents)).toBeInTheDocument() 
  expect(screen.queryByText(hats.contents))
  .not.toBeInTheDocument()
})
```

Incrível! Agora temos um único teste que verifica todo o comportamento do componente. E esse teste vai passar mesmo se o nome do estados for `openIndex`, `openIndexes`, ou `tacosAreTasty`, não importa!


## Conclusão

Acredito que é seguro dizer que normalmente os desenvolvedores não tem tanta vontade assim de escrever testes, muito menos seguindo metolodogias como TDD, BDD, FDD, DDD ou outras.

Entretanto, todos sabem da sua real importância e acredito que essa cultura de só codar sem implementar testes vai acabar ficando pra trás, pois sabemos o quanto contribui para a confiabilidade do código e isso é o que todo mundo quer!

Já vi gente dizer que escrever testes pra front-end é um caos, pois não existia padrão ou alguma ferramenta mais simples de configurar.

Entretanto, como vimos nesse material, já não está mais tão ruim assim implementar os testes no front-end e espero que surjam cada vez mais autores como o [Kent C. Dodds](https://kentcdodds.com/about) para trazer essas abordagens práticas de testes no front-end.

Além disso, as ferramentas tem avançado também como vimos com o React Test Library, e diversas outras como o Enzime, e o Jest sendo este o mais popular, talvez por ser nativo do create-react-app.

Por fim, agora que aprendemos "o que" testar, podemos facilmente integrar esse conhecimento com o estudo dessas ferramentas e melhorar ainda mais a qualidade nos nossos testes.

Caso queira conhecer agora o "como" testar, deixo algumas recomendações abaixo que podem introduzir o assunto: 

"Guia rápido de testes no front-end" - Thayse Onofrio
 https://dev.to/thayseonofrio/guia-rapido-de-testes-no-front-end-2lpc
"Testes automatizados em React" - Thiago Ferreira
https://medium.com/luizalabs/testes-automatizados-em-react-e431db826d65
"Jest: Escrever testes nunca foi tão divertido" - Eduardo Rabelo
https://oieduardorabelo.medium.com/jest-escrever-testes-nunca-foi-t%C3%A3o-divertido-5f0e1950ba10

---

**Referências:**
"How to know what to test" - Kent C. Dodds 
[https://kentcdodds.com/blog/how-to-know-what-to-test](https://kentcdodds.com/blog/how-to-know-what-to-test)
"Avoid the Test User" - Kent C. Dodds 
[https://kentcdodds.com/blog/avoid-the-test-user](https://kentcdodds.com/blog/avoid-the-test-user)
"Testing Implementation Details" - Kent C. Dodds 
[https://kentcdodds.com/blog/testing-implementation-details](https://kentcdodds.com/blog/testing-implementation-details)