DEV Community

Cover image for Testing Library React em 4 minutos...
Robson Neres
Robson Neres

Posted on

Testing Library React em 4 minutos...

Para começar vamos entender o que é o Testing Library. Bom para simplificar é uma biblioteca voltada para testes unitários de aplicações frontend.
Link da biblioteca: https://testing-library.com/

Show!
Agora vamos começar pois temos 4 minutos...rs

1) Primeiro passo é ter um projeto react, então vamos criar um básico.

  • Separe uma pasta onde vamos criar nosso projeto
  • Abra o terminal nessa pasta e digite o comando abaixo
  • npx create-react-app my-app (my-app é o nome do seu projeto)
  • Abra a pasta gerada pelo comando no terminal com: cd my-app
  • Rode o projeto digitando o seguinte comando no terminal: npm run start

2) Bom demais, nesses comando conseguimos ter um projeto react rodando e ainda já deixar instalado a biblioteca testing-library. Caso queira instalar em algum projeto existente basta fazer os passos abaixo:

  • npm install --save-dev @testing-library/react

OBS: com --save deixamos documentado no package.json o que instalamos para quem clonar nosso repositório conseguir rodar sem problemas, o -dev é por que utilizamos essa lib(biblioteca) somente para testar em ambiente de desenvolvimento e não queremos que afete o pacote gerado para deploy em produção! ;-)

3) Agora vamos fazer nosso primeiro teste:

  • Crie um arquivo no seu projeto no mesmo lugar que estiver o arquivo que deseja testar com o nome do component/arquivo, ex: button.test.jsx

OBS: Usamos .test quando é um arquivo de testes completos dos comportamento do componente e vamos fazer um regressivo mesmo. E quando queremos apenas fazer uma documentação/especificação do componente usamos .spec, ou seja, fazemos um arquivo desses quando queremos testar apenas o básico e seguindo muitas vezes as premissas que fizeram criar o componente.

  • Então vamos mostrar nosso componente e estudar o que pode ser testado:
import React from "react";
import PropTypes from "prop-types";
import cs from "classnames";
import './Button.scss';


const Button = ({ kind, gtmCategory, gtmAction, gtmLabel, onClick, className, children, ...otherProps }) => {
    return <button
    onClick={onClick}
    {...otherProps}
    className={cs(`button ${className}`, kind ? `button--${kind}` : null)}
    data-gtm-event-category={gtmCategory}
    data-gtm-event-action={gtmAction}
    data-gtm-event-label={gtmLabel}
    >
        {children}
    </button>
};

Button.propTypes = {
    onClick: PropTypes.func,
    children: PropTypes.any,
    kind: PropTypes.any,
    gtmCategory: PropTypes.any,
    gtmAction: PropTypes.any,
    gtmLabel: PropTypes.any,
    otherProps: PropTypes.any
};

export default Button;

Enter fullscreen mode Exit fullscreen mode
  • Então vamos para nosso teste:
import React from 'react';
import { fireEvent, render } from '@testing-library/react';
import Button from './Button';

test('render button', () => {
    const { getByText } = render(<Button>TESTE 1</Button>);
    const linkElement = getByText('TESTE 1');
    expect(linkElement).toBeInTheDocument();
});

test('render button with kind', () => {
    const { getByText } = render(<Button kind="disabled">TESTE 2</Button>);
    const linkElement = getByText('TESTE 2');
    expect(linkElement).toBeInTheDocument();
});
Enter fullscreen mode Exit fullscreen mode
  • Algumas explicações sobre nossos testes:
  • Fizemos primeiro um render básico do nosso componente passando nenhuma props. Nesse teste dizemos o render do componente na linha 6, utilizando uma das facilidades da lib testing-library pois ela permite pesquisar no código renderizado um text especifico, que no nosso caso foi o título do botão.

  • Então para testar mesmo nosso primeiro render esperamos que encontrasse nosso titulo do botão na tela renderizada, utilizando o expect, na linha 8. Nesse caso o expect é uma das ferramentas do próprio Jest(lib que cuida dos testes).

  • No segundo teste fizemos uso de uma variação de layout que nosso componente permitia, passando uma props a mais e vendo se conseguimos pegar mesmo assim o título do mesmo.

  • Agora se perguntarmos se esses testes estão cobrindo todo nosso componente o que você diria? Se você disse não então prestou atenção no nosso código e viu que temos também uma ação no nosso botão e não passamos por ela, abaixo vamos escrever esse teste juntos:

import React from 'react';
import { fireEvent, render } from '@testing-library/react';
import Button from './Button';

test('render button', () => {
    const { getByText } = render(<Button>TESTE 1</Button>);
    const linkElement = getByText('TESTE 1');
    expect(linkElement).toBeInTheDocument();
});

test('render button with kind', () => {
    const { getByText } = render(<Button kind="disabled">TESTE 2</Button>);
    const linkElement = getByText('TESTE 2');
    expect(linkElement).toBeInTheDocument();
});

test('render and click button', () => {
    const mockFunction = jest.fn();
    const { getByText } = render(
        <Button kind="disabled" onClick={()=>mockFunction()}>TESTE 2</Button>
    );

    fireEvent.click(getByText('TESTE 2'));
    expect(mockFunction).toBeCalled();
})
Enter fullscreen mode Exit fullscreen mode

Nesse último teste fizemos uma function mocada usando jest.fn() que simula uma function e contabiliza quando é acionada, assim fica fácil de testarmos o que esperamos. Basicamente renderizamos nosso botão, depois usamos o fireEvent para disparar um click no botão e usamos no expect a nossa function mocada que nos informa se foi acionada ou não, e então temos nosso resultado esperado com o toBeCalled, ou seja, essa function foi acionada? simm

Com isso terminamos o básico de um teste de componente, seguindo algumas coisas básicas e muito utilizadas em todos testes...

ahh caso queira ver o quanto que cobrimos nosso componente basta executar esse comando no terminal:
npm run coverage

Então vai ser gerado uma pasta na raiz do seu projeto com o nome coverage e então basta abrir a pasta dentro e abrir no navegador o index.html, ai vai ter uma amostra de coberturas de todos seus componentes e telas. Nesse caso ficou assim o do nosso componente:

image

Top comments (2)

Collapse
 
brunolucena profile image
Bruno A Lucena

Show, já usei essa biblioteca em um projeto legado mas nunca entendi muito bem não, esclareceu bastante coisa. Vou tentar usar de novo.

Collapse
 
wellesaraujo profile image
Wellington Araujo da Silva

Muito bom. Claro e objetivo no uso da biblioteca. Estou aprendendo bastante a respeito de testes unitários usando o Testing Library.