Felipe Cesar

    Simplificando testes com Testing Library

    Fala pessoal! Neste artigo vamos falar sobre Testing Library dando continuidade ao artigo anterior. Se quiser pode baixar o repositório para acompanhar o conteúdo.

    O que é?

    Como a própria documentação diz, a Testing Library é uma família de pacotes que ajudam a testar componentes de UI do ponto de vista do usuário.

    Ele pode ser usado em aplicações com JavaScript puro ou com frameworks, incluindo React, Vue e Angular.

    Como estamos usando React, vamos instalar o pacote próprio para ele no nosso projeto:

    npm i -D @testing-library/react

    Após instalar, altere o arquivo Highlight.test.js, removendo a função render que criamos e importando a da Testing Library. Você também pode remover o afterEach, agora isso é feito por baixo dos panos.

    import { render } from "@testing-library/react";
    import Highlight from "./Highlight";
    
    test("renders a value", () => {
      const value = "3000";
      render(<Highlight value={value} />);
      expect(document.body.textContent).toBe(value);
    });
    
    test("renders another value", () => {
      const value = "5000";
      render(<Highlight value={value} />);
      expect(document.body.textContent).toBe(value);
    });

    Removendo detalhes de implementação

    Repare que estamos sempre verificando se o texto da página toda é o valor esperado.

    Se houvessem outros elementos com textos na página, seria necessário usar um querySelector, com um seletor específico para o elemento.

    expect(document.querySelector("div").textContent).toBe(value);

    Isso funcionaria, mas imagine que por algum motivo o elemento deixa de ser uma div e passa a ser um p.

    Sempre que uma mudança desse tipo precisar ser feita você vai alterar o componente e os testes. Esse é um detalhe de implementação que normalmente não faz diferença para o usuário.

    Para resolver isso a Testing Library conta com queries que se assemelham a forma como um usuário encontra os elementos na página. Podemos usá-las importando o objeto screen, da seguinte forma:

    import { render, screen } from "@testing-library/react";
    import Highlight from "./Highlight";
    
    test("renders a value", () => {
      const value = "3000";
      render(<Highlight value={value} />);
      expect(screen.getByText(value)).toBeTruthy();
    });

    Note que o expect mudou um pouco, agora estamos utilizando o método getByText para obter um elemento com aquele texto.

    Se o elemento for encontrado o teste deve passar, mas repare que passamos a utilizar toBeTruthy para fazer a asserção. Será que não tem uma asserção que faça mais sentido?

    Se tiver dúvidas sobre quando um valor é Truthy, esse link do MDN deve te ajudar.

    Adicionando mais asserções

    Quando testamos componentes de UI é bem comum verificar se o elemento está na tela, se ele tem um atributo, uma classe, etc.

    O Jest não conta com asserções para esse tipo de situação, mas ele nos permite adicioná-las, e a Testing Library conta com uma biblioteca própria para isso, o jest-dom.

    Execute o seguinte comando:

    npm i -D @testing-library/jest-dom

    Agora altere o arquivo Highlight.test.js, importando o jest-dom e utilizando a asserção toBeInTheDocument.

    import { render, screen } from "@testing-library/react";
    import "@testing-library/jest-dom";
    import Highlight from "./Highlight";
    
    test("renders a value", () => {
      const value = "3000";
      render(<Highlight value={value} />);
      expect(screen.getByText(value)).toBeInTheDocument();
    });

    Dessa forma, fica bem claro que estamos verificando se um elemento está no DOM.

    jest-dom global

    Nesse exemplo importamos o jest-dom direto no arquivo do teste, mas não precisamos fazer dessa forma, podemos importá-lo de forma global.

    Para fazer isso, crie o arquivo setupTests.js dentro de src e adicione a seguinte linha:

    import "@testing-library/jest-dom/extend-expect";

    Feito isso, altere o arquivo jest.config.js para que fique assim:

    module.exports = {
      testEnvironment: "jsdom",
      setupFilesAfterEnv: ["<rootDir>/src/setupTests.js"],
    };

    Pronto! Com isso não precisamos mais importar o jest-dom nos testes.

    Conclusão

    Nesse artigo tivemos um primeiro contato com a Testing Library, simplificamos testes e asserções, removendo detalhes de implementação e deixando-os mais próximos da visão do usuário.

    A Testing Library conta com muitos recursos que facilitam os testes, e vamos explorá-los mais ainda nos próximos artigos. Se quiser ver como ficou o código pode acessar esse repositório.

    Se tiver alguma dúvida ou sugestão deixa um comentário, bora trocar uma ideia. Abraço!