Testes de componentes React com Jest e Enzyme

Márcio Santos
Aurum Tech
Published in
6 min readFeb 7, 2019

Recentemente na Aurum iniciamos um processo de migração tecnológica no front end do sistema Astrea partindo do framework AngularJS para o tão falado React. Aproveitamos a situação para tomar algumas decisões com a finalidade de aumentar a qualidade do código e consequentemente do produto, para não cairmos nos mesmos problemas que enfrentamos na tecnologia legada, decisões tais como style guide, configuração de lint e o assunto deste post: testes unitários de componentes. Serão apresentados os conceitos das bibliotecas Jest e Enzyme, como configurá-las em um projeto React e um apanhado geral de como abordamos os testes de componentes e soluções utilizadas aqui na Aurum.

Jest

Jest é uma biblioteca que fornece utilitários para testes em javascript, criada pelo Facebook e famosa por sua velocidade e facilidade em iniciar os testes de seu código com zero configuração. Para projetos em react criados com create-react-app não é necessária nem mesmo a instalação, pois ela já vem inclusa.

Enzyme

Enzyme foi criado pelo Airbnb e é definido como:

Utilitário de testes em javascript para React que facilita verificar, manipular, e percorrer as saídas produzidas por seus components React.

Criando e configurando um projeto React

Como o foco deste post não é demonstrar como uma aplicação React funciona, apenas mostrarei como criar utilizando o comando create-react-app .

create-react-app react-enzyme-tests
cd react-enzyme-tests

Configurando o Jest

Caso o seu projeto React tenha sido criado manualmente e não utilizando create-react-app , basta instalá-lo como dependência de desenvolvimento usando yarn ou npm:

yarn add --dev jest

Configurando o Enzyme

Para configurar o enzyme, instale a biblioteca como dependência de desenvolvimento utilizando yarn ou npm:

yarn add --dev enzyme enzyme-adapter-react-16

Você deve ter notado que além da biblioteca do enzyme, instalamos também um adapter cuja versão bate com a versão do React instalada. O Enzyme disponibiliza adapters para todas as versões do React. Você terá acesso a mais informações a respeito dos adapters neste link.

Arquivo de configuração do Enzyme

Em src crie um arquivo javascript para conter a configuração do Enzyme.

Arquivo de configuração do enzyme

Mais adiante serão explanados o porquê e o uso das exportações desta configuração.

Estrutura do projeto

Você pode criar dois diretórios dentro de src components e components/__tests__ e colocar seus componentes no primeiro e os respectivos testes dentro do segundo, ou colocar o arquivo de teste junto com o do componente testado. Aqui na Aurum nós optamos pela segunda opção pelo fato de que fica mais fácil localizar o arquivo de teste de cada componente ao navegar pela estrutura de diretórios do projeto.

Métodos de teste com Enzyme

Shallow

Shallow rendering é a forma básica de testar um componente utilizando Enzyme, pois limita a renderização apenas ao componente que está sendo testado, ou seja, os filhos não são renderizados. Esse método é ótimo quando se deseja testar componentes de apresentação apenas, ou quando a mudança de comportamento em um componente filho não afeta o componente pai.

Mount e Render

Ambos mount e render efetuam a renderização total do componente incluindo os componentes filhos. A diferença existente entre os dois, é que o método mount executa os ciclos de vida do componente e o segundo apenas a função render.

Para exemplificar o funcionamento destes métodos, foi criado um componente de classe que representa uma lista de itens a qual mapeia componentes de itens da lista.

Componente de lista de itens
Componente de item da lista

Desta forma, foram criados para cada um dos componentes seus respectivos arquivos de teste. No caso do componente ListComponent foram criados dois testes, um utilizando shallow e outro mount .

Suit de testes do componente ListComponent

Execução dos testes

Para executar os testes, basta simplesmente executar o comando yarn test e você deverá perceber em seu console uma saída semelhante a esta:

Test Suites: 2 passed, 2 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 5.169s
Ran all test suites related to changed files.

Caso você queira rodar seus testes com cobertura basta acrescentar o parâmetro --coverage e será exibido em seu console um relatório de cobertura além de ser gerado um diretório chamado coverage o qual contém os arquivos para você visualizar o relatório em seu navegador.

O comando wrapper.debug() contido no trecho de código apresentado anteriormente retorna a árvore do componente que foi renderizada pelo teste. No caso do shallow o resultado impresso no console foi:

<div data-test="list">
<ListItemComponent label="Aurum" onClick={[Function: bound ]} />
<ListItemComponent label="Astrea" onClick={[Function: bound ]} />
</div>

Nota-se que a renderização aconteceu de forma raza, não havendo renderização dos nodos filhos, já no caso do mount a saída no console exibe a árvore completa.

<ListComponent items={{...}}>
<div data-test="list">
<ListItemComponent label="Aurum" onClick={[Function: bound ]}>
<div>
<button data-test="listItem" onClick={[Function: bound ]}>
Aurum
</button>
</div>
</ListItemComponent>
<ListItemComponent label="Astrea" onClick={[Function: bound ]}>
<div>
<button data-test="listItem" onClick={[Function: bound ]}>
Astrea
</button>
</div>
</ListItemComponent>
</div>
</ListComponent>

A função find busca cada nodo na árvore de renderização do wrapper que bate com o seletor informado. O Enzyme suporta qualquer tipo de seletor CSS para buscar esses nodos, portanto é possível utilizar seletores de classe, de elemento e por id. Além disso é permitida a composição de seletores.

Mock de funções

Com Jest, é possível efetuar o mock de funções. Uma das aplicações disto é quando queremos verificar se determinada função foi chamada na ação de um click, por exemplo.

Teste utilizando o mock de funções do Jest

Snippets

Conforme você vai criando testes pros seus componentes, começa a notar que a estrutura do teste é a mesma, que pra começar a escrever um teste você precisa replicar aquela estrutura básica que consistem nos imports, num setup ou beforeEach, no describe e no teste padrão de renderização do componente. Algumas IDE’s dão suporte a snippets, que são templates que facilitam a criação de trechos de códigos com padrão repetitivo. Visual Studio Code permite a criação de snippets personalizados e aproveitamos essa funcionalidade para criar um com nosso padrão de testes.

"Test snippet": {
"prefix": "aut",
"body": [
"import React from \"react\";",
"import { shallow } from \"enzymeHelper\";",
"import ${TM_FILENAME_BASE/\\.test//} from \"./${TM_FILENAME_BASE/\\.test//}\";",
"",
"const setup = () => {",
" const props = {};",
"",
" return {",
" props,",
" wrapper: shallow(<${TM_FILENAME_BASE/\\.test//} {...props} />)",
" };",
"};",
"",
"describe(\"${TM_FILENAME_BASE/\\.test//} test suit\", () => {",
" it(\"renders without error\", () => {",
" const { wrapper } = setup();",
" expect(wrapper.exists()).toBeTruthy();",
" });",
"});"
],
}
Execução do snippet e código padrão de teste

Conclusão

Neste post eu busquei passar apenas uma visão geral a respeito de Jest e Enzyme, nem de perto pude apresentar a maioria das funcionalidades que essas duas bibliotecas trazem e das possibilidades que essas funcionalidades nos fornecem. Além disso, espero que eu tenha ao menos passado a mensagem de que testar um componente React não é algo doloroso pois essas bibliotecas facilitam e muito a nossa vida como desenvolvedor e com a prática você com certeza pegará gosto em entregar seus componentes com uma cobertura de teste adequada.

Caso esse post tenha despertado seu interesse, seguem alguns links úteis:

--

--