Pensando fora da caixa: não testar implementação

Boa parte dos testes que fazemos, no backend, ou em frameworks como Angular, testam implementação. Mas podemos facilmente mudar esse pensamento quando se trata de testes de unidade no frontend.

📑

O que significa "testar implementação"?

Em programação, falamos muito sobre implementação, mas o que significa isso?

Basicamente, implementação refere-se ao código escrito, ao que foi implementado, aos detalhes e regras de negócio. Então podemos dizer que um método/função, ou um if/else, ou até mesmo um for/while, etc, são implementações, mas o conceito vai muito além, procure mais sobre, vai ser um conhecimento muito válido.

Sendo menos genérico, podemos pegar o seguinte caso:

function formatarTextoParaCaixaAlta (text) { return text.toUpperCase() }

Essa é a implementação de um método que converte um texto simples em minusculas, para todas as letras em maiúsculas.

E um teste de implementação em cima desse código, ficaria da seguinte forma:

test("deve retornar todos os caracteres do texto em maiúsculas", () => { const result = formatarTextoParaCaixaAlta("texto todo em minusculas") expect(result).toEqual("TEXTO TODO EM MINUSCULAS") })

Neste teste, nós chamamos a função diretamente, passamos o valor, guardamos o resultado e fazemos a validação.

Esse é um exemplo bem simples de teste de unidade que testa a implementação do método.

Um pouco sobre responsabilidades

Trabalhando com frontend em várias empresas diferentes, notei uma coisa, a cultura de testes no frontend é muito fraca. Muitas pessoas falam que testam e tudo mais, mas no dia a dia, deixam várias coisas para trás devido à correria, ou por falta de conhecimento/familiaridade.

Então é muito mais fácil termos referencias sobre testes vindas do backend, e no backend testes que testam a implementação são muito comuns.

O cliente de uma aplicação backend, uma API ou micro serviço, normalmente é outro sistema, ou um frontend, ou seja, os clientes que consomem o backend são outros códigos, e não pessoas reais, humanos interagindo via uma interface.

Mas no frontend temos o inverso, que consome nosso código são humanos, eles interagem com periféricos como mouses, teclados, leitores de tela, plugins, etc.

Então temos que ter em mente que nosso cliente, a pessoa do outro lado da tela, não faz ideia que você tem um método chamado `getUserById()` quando ela quer buscar uma pessoa específica.

Essa pessoa só quer digitar um nome em um campo de busca e ver o resultado. Logo tentamos aproximar nossos testes dessas interações e comportamentos.

Fragilidades no frontend

O frontend em muitos casos é mais volátil devido o fato de ter muito texto, hierarquias de elementos HTML, e funções simples para executar tarefas, todas essas coisas, tem em comum a fragilidade.

É muito fácil quebrar um teste porque um texto mudou, ou porque o nome de uma função mudou. E isso não quer dizer que o teste quebrou de verdade, pode ser um falso positivo, podemos ter dores de cabeça corrigindo testes que quebraram porque o título da página mudou ou uma função de conversão de datas mudou de nome.

Por isso, encorajamos os testes que evitam implementação. E para isso temos ferramentas como a biblioteca Testing Library, que nos permitem trabalhar numa camada acima do DOM, como se fosse uma pessoa de fato usando o produto, sendo assim, criamos cenários e fluxos de execução que sejam os mais próximos do que a pessoa faria.

Mas calma, você deve estar pensando que isso é um teste End To End (e2e). E você está enganado, não tem nada a ver, é apenas uma abordagem diferente nos testes de unidade e integração, que deixam os testes mais concisos e estáveis, evitando quebras por falsos positivos, focando na regra de negócio e nos comportamentos esperados.

A Testing Library segue o princípio que quanto mais o teste se assemelha da forma que a aplicação é utilizada, mais confiança o teste passa. O que também nos força a pensar mais em critérios de acessibilidade para nosso código. Algumas boas práticas de SEO e acessibilidade na web estão alinhadas. Isso é muito importante no contexto de alguns projetos, dado que impacta no acesso orgânico, por exemplo.

Veja exemplos de como criar testes melhores utilizando a testing library no próximo post.

Nertec logo