Como criar um componente React com TDD

Quando começamos a estudar sobre TDD (Test Driven Development) é comum surgirem algumas dúvidas, por exemplo, o que testar? como escrever testes antes do código de produção?
Este é um artigo bem prático que tem como objetivo acabar com algumas dessas dúvidas se tratando de aplicações React.
Test Driven Development
O Test Driven Development ou TDD significa Desenvolvimento Orientado a Testes e é uma prática que consiste em um ciclo curto de três passos, conhecidos como Red/Green/Refactor.
  • Red: Primeiro escrevemos um teste que falha, para alguma funcionalidade que ainda será desenvolvida.
  • Green: Com o teste criado, escrevemos uma solução simples para fazê-lo passar.
  • Refactor: Por último refatoramos, ou seja, melhoramos o código.
  • Esse ciclo deve se repetir várias vezes durante todo o desenvolvimento.
    Tendo isso em mente podemos ver como esse ciclo funciona na prática.
    Escrevendo um teste que falha
    Para acompanhar o desenvolvimento você pode baixar o repositório e fazer o checkout na branch exercise-01-start.
    Após baixar o código, crie a pasta src/components e adicione o arquivo Highlight.test.js com o seguinte conteúdo:
    import ReactDOM from "react-dom";
    import Highlight from "./Highlight";
    
    test("renders a value", () => {
      const container = document.createElement("div");
      document.body.appendChild(container);
    
      ReactDOM.render(<Highlight />, container);
    
      expect(document.body.textContent).toBe("3000");
    });
    A função test recebe uma descrição do teste como primeiro parâmetro. É uma boa prática sempre começar com um verbo no presente. O segundo parâmetro é uma função anônima com o código do teste.
    Uma const chamada container tem como valor uma div, que é o elemento onde o componente será renderizado.
    O método render do ReactDOM é utilizado para renderizar o componente.
    Por último, é feita uma chamada a função expect, ela fornece uma lista de métodos que nos permitem fazer diferentes asserções. Neste caso, verificamos se o textContent da página é 3000.
    Execute o comando npm test, veja que o teste está falhando, isso já era esperado, porque ainda estamos no primeiro passo do ciclo.
    Fazendo o teste passar
    Agora crie o arquivo Highlight.js dentro de src/components, com o seguinte conteúdo:
    const Highlight = () => <div>3000</div>;
    
    export default Highlight;
    Por enquanto não precisamos de nada além disso para que o teste passe.
    Refatorando o código
    Adicionamos um valor "na mão", apenas para o teste passar, mas vamos precisar que o componente funcione com outros valores, para isso vamos fazer a seguinte alteração no teste:
    ReactDOM.render(<Highlight value="3000" />, container);
    E logo em seguida no componente:
    const Highlight = ({ value }) => <div>{value}</div>;
    Fizemos essas mudanças na intenção ter um código melhor, que funcione com diferentes valores, mas quem garante que funciona?
    Repetindo o ciclo
    Para garantir que o componente está funcionando como esperado, podemos repetir o ciclo escrevendo outro teste. Adicione o seguinte código no arquivo Highlight.test.js:
    test("renders another value", () => {
      const container = document.createElement("div");
      document.body.appendChild(container);
    
      ReactDOM.render(<Highlight value="5000" />, container);
    
      expect(document.body.textContent).toBe("5000");
    });
    Execute os testes novamente. Note que o segundo teste falha e com um erro bem estranho:
    Expected substring: "5000"
    Received string:    "30005000"
    Isso acontece porque adicionamos um elemento ao body e não o removemos após a execução do primeiro teste.
    Removendo efeitos colaterais
    Para que o teste passe, devemos garantir que o que foi feito em um não interfira no resultado do outro. Podemos remover todos os elementos do body após cada teste. A função afterEach do Jest permite fazer isso de uma forma bem simples. Adicione o seguinte código antes dos testes:
    afterEach(() => {
      document.body.innerHTML = "";
    });
    Removendo código duplicado
    Se olharmos bem o arquivo de teste, podemos ver claramente que alguns itens se repetem. Essa é a hora em que devemos resistir a tentação de passar para o próximo componente e trabalhar duro para deixar nosso código o mais limpo possível.
    Crie a seguinte função no arquivo de testes:
    function render(component) {
      const container = document.createElement("div");
      document.body.appendChild(container);
    
      ReactDOM.render(component, container);
    }
    Ela contém o código que se repete nos dois testes. Com essa função, podemos refatorar os testes, tornando-os mais simples:
    test("renders a value", () => {
      const value = "3000"; // Arrange
      render(<Highlight value={value} />); // Act
      expect(document.body.textContent).toBe(value); // Assert
    });
    
    test("renders another value", () => {
      const value = "5000"; // Arrange
      render(<Highlight value={value} />); // Act
      expect(document.body.textContent).toBe(value); // Assert
    });
    Para saber se um teste é bom, você deve ser capaz de identificar cada uma das seguintes etapas:
  • Arrange: Faz o setup das dependências de teste
  • Act: Executa o código de produção em teste
  • Assert: Verifica se as expectativas são atendidas
  • Mas isso não é tudo, podemos deixar os testes ainda melhores, garantindo que eles atendam alguns requisitos:
  • Sejam descritivos
  • Independentes de outros testes
  • Não tenham efeitos colaterais
  • O ideal é sempre buscar atender todos esses requisitos, você vai ganhar muito com isso e provavelmente evitar algumas dores de cabeça no futuro.
    Conclusão
    Nesse artigo desenvolvemos um componente React seguindo o TDD, fiz o possível para que não ficasse muito longo.
    Se esse conteúdo te ajudou ou se ficou alguma dúvida, deixa um comentário, isso me ajuda a saber se devo criar mais conteúdo desse tipo.
    Ah! O código completo pode ser encontrado nesse repositório. Abraço!

    39

    This website collects cookies to deliver better user experience

    Como criar um componente React com TDD