Escreva testes. Não muitos. Mas mais de integração.

Tradução do artigo Write Tests. Not too many. Mostly Integration do Kent C Dodds.
Revisão: Raul Felipe de Melo.

Guillermo Rauch tweetou isso há um tempo. Vamos mergulhar fundo para ver o que significa.

Nota: Isso é um post da minha newsletter. Eu publico cada um deles depois de ter enviado por e-mail duas semanas antes. Se inscreva para ter mais conteúdo como esse mais cedo na sua caixa de entrada! 💌

Traduções disponíveis atualmente:

Coreano
Russo

TestingJavaScript.com — Aprenda uma forma inteligente e eficiente de testar suas aplicações em JavaScript.

Eu fiz uma palestra sobre esse post que você pode assistir aqui:

Há um tempo atrás, Guillermo Rauch (Criador do Socket.io e fundador da Zeit.co (Companhia por trás de inúmeros projetos incríveis sendo lançados ultimamente)) twittou algo profundo.

Escreva testes. Não muitos. Mas mais de integração.

Isso é profundo embora curto. Vamos analisa-lo.

Escreva testes.

Sim, para a maioria dos projetos você deve escrever testes automatizados. Se você valoriza seu tempo. É muito melhor ter que lidar com bugs localmente num teste do que receber uma ligação ás 2h da manhã para corrigi-los. Frequentemente eu me encontro poupando tempo quando arrumo tempo para escrever testes. Pode demorar ou não para implementar o que estou construindo, mas eu (e os outros) vão provavelmente economizar o tempo de manutenção.

O que você deve pensar quando escrever testes é quanta confiança eles trazem de que seu projeto está livre de erros. Tipagem estática e linters, como Flow e ESLint podem trazerem muita confiança, e, caso você não esteja utilizando essas ferramentas, eu recomendo muito que você dê uma olhada. Dito isso, mesmo linguagens fortemente tipadas devem ter testes. Tipagem e linters não garantem que a lógica do seu negócio está livre de erros. Então você ainda deve aumentar ainda mais a confiança com um bom ambiente de testes.

Não muitos.

Eu já ouvi gerentes e times obrigados a cobrir 100% de testes o código de suas aplicações. Isso é uma péssima idéia. O problema é que seu rendimento cai quando seus testes ultrapassam 70% de cobertura (Eu escolhi esse número… não foi ciência.). Por que? Bem, quando você se esforça 100% do seu tempo nisso, você vai se pegar testando coisas que não precisam serem testadas. Coisas que não tem lógica (então qualquer erro poderia ser encontrado usando ESLint e Flow). Manter testes como esses realmente vão atrasar você e o seu time.

Você também se encontrará testando detalhes de implementação apenas para você ter certeza de que passou por aquela linha de código que é difícil reproduzir em um ambiente de testes. Você realmente deveria evitar testar detalhes de implementação porque não dá muita confiança de que sua aplicação está funcionando e isso vai atrasar quando for refatorado. Você raramente deve mudar os testes quando refatorar seu código.

Eu devo mencionar que quase todos meus projetos open sources tem 100% de código coberto por testes. Isso porque a maioria deles são pequenas bibliotecas e ferramentas que são reutilizadas em muitos casos diferentes (qualquer quebra pode trazer sérios problemas em muitos projetos que os utilizam) e eles são relativamente fáceis de cobrir 100% com testes.

Mas mais de integração.

Existem diferentes tipos de testes (Veja minha apresentação de 5 minutos sobre isso no Fluent Conf: “What we can learn about testing from the wheel”). Cada um deles tem seus prós e contras. Os 3 tipos de testes mais comum de quando estamos falando de testes automatizados são: Unitários, Integração e End to End (E2E).

Aqui está um slide do meu Frontend Masters workshop: “Testing JavaScript Applications”

testing pyramid

Esta pirâmide de testes é uma combinação de uma outra pirâmide que eu encontrei no blog do Martin Fowler e outra do blog de Teste da Google.

Como mencionado, a pirâmide mostra de baixo para cima: Unitário, Integração e End to End. Quanto mais você sobe a pirâmide, mais demorado é pra escrever/rodar e mais caro (em termos de tempo e recursos) para criar/manter os testes. Por esses motivos, isso indica que você deve gastar mais tempo em testes unitários.

Uma coisa que não é mostrada é que conforme você sobe a pirâmide, mais confiança cada nível de teste te traz. Você tem mais retorno do seu esforço. Enquanto testes End to End são mais lentos e caros que testes unitários, eles trazem muito mais confiança de que sua aplicação está funcionando como esperado.

É por causa disso que eu criei o “Teste Troféu 🏆 “.

Meu tweet mais retweetado de todos tem a ver com o principal problema com testes unitários:

Ainda amo esse. Testar unitários são tipo: “Olha como está funcionando.”.
Homem em três partes. Pernas correndo, braços fazendo flexões e a cabeça lendo.

Nós estamos escrevendo testes que verificam o homem correndo, fazendo flexões e lendo, mas o homem não está interagindo com as outras partes do seu corpo muito bem. Não importa se o componente do seu botão chama a função no onClick se a função não faz a requisição da forma correta, com os dados certos! Então, embora seja uma boa idéia ter alguns testes unitários para verificar cada parte funcionando isoladamente, não adianta se você também não verificar se elas funcionam juntas.

Testes integração trazem um grande equilíbrio de benefícios entre confiança e velocidade/custo. É por isso que é aconselhável gastar a maior parte (não todo, lembre-se) do seu esforço nisso.

Como escrever mais testes de integração.

A linha entre integração e testes unitários é um pouco confusa. Independentemente disso, eu acho que a maior coisa que você poderá fazer para escrever mais testes de integração é parar de mockar muitas coisas. Quando você mocka algo, você está basicamente removendo toda confiança na integração entre o que você está testando e o que foi mockado. Eu entendo que as vezes isso pode não ser útil (mesmo que você discorde). Você não quer realmente enviar e-mails ou carregar um cartão de crédito sempre que executar os testes, mas na maior parte do tempo você pode evitar mockar esses dados e você vai se sentir melhor por isso.

Se você utiliza React então isso inclui renderização superficial (shallow rendering). Eu tenho dito há um tempo que sinto que renderização superficial é como testar os detalhes de implementação. Para mais 3 minutos falando sobre isso (e outras dicas de testes em React) confira esse episódio do podcast 3 minutes.

Espero que isso os ajude. Boa sorte a todos!! 👍

Também não deixe de ver:

  • blog.kentcdodds.com — Eu comecei a postar em meu próprio Medium. Não deixe de me seguir lá.
  • hacktoberfest — Entre com sua conta do Github e se você fazer 4 pull requests no mês de Outubro, eles vão te enviar uma camiseta gratuitamente. Fácil, né
  • draggable — Provavelmente uma das demos mais legais de um projeto que eu já vi.
  • Funky Karts demo — Um jogo muito legal que foi criado com WebAssembly. Obrigado por compartilhar, Jay Phelps!

OBS: Se você gostou desse artigo, se inscreva, me siga no twitter, pague meu almoço e compartilhe com seus amigos 😀

Também, retwteetando é uma ótima maneira de compartilhar com seus amigos: