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

Latest comments (2)

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.

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.