Como escrever seu primeiro teste unitário em JavaScript
Raphael Mun
28 de outubro de 2022
0 minutos de leituraTestar o código é o primeiro passo para torná-lo seguro. Uma das melhores maneiras de fazer isso é usar testes unitários, garantindo que cada uma das funções menores de um aplicativo se comporte como esperado — especialmente quando o aplicativo recebe entradas incomuns, inválidas ou potencialmente prejudiciais.
Por que fazer testes unitários?
Há várias abordagens para testes unitários. Entre os principais objetivos desses testes estão:
Verificar funcionalidades: os testes unitários garantem que o código faça o que deve fazer — e não faça o que não deve, origem da maioria dos bugs.
Prevenir regressões no código: quando encontramos um bug, adicionar um teste unitário para verificar aquele cenário impede que alterações no código façam o bug voltar no futuro.
Documentar o código: com os testes unitários certos, um conjunto completo de testes e resultados especifica como o aplicativo deve funcionar.
Proteger seu aplicativo: os testes unitários podem verificar se há vulnerabilidades exploráveis, como as que permitem uma injeção de SQL maliciosa.
Definição do escopo e escrita de testes unitários
Um framework de testes unitários permite escrever e automatizar testes com rapidez, além de integrá-los aos processos de desenvolvimento e implantação. Esses frameworks costumam oferecer suporte a testes tanto no front-end quanto no back-end de código JavaScript.
Confira algumas orientações gerais para escrever testes unitários de desempenho e criar código que possa ser testado.
Mantenha os testes unitários curtos e simples
Não sobrecarregue os testes unitários. Cada teste deve ter apenas algumas linhas de código e verificar partes pequenas e funcionais do aplicativo.
Considere casos de teste positivos e negativos
É útil escrever um teste para confirmar que uma função é executada corretamente. No entanto, é muito mais eficaz criar um conjunto mais amplo de testes para verificar se a função falha como deveria quando é usada incorretamente ou em casos extremos. Esses testes negativos podem ser ainda mais valiosos, pois ajudam a prever situações inesperadas, como quando uma função deve gerar uma exceção ou como deve lidar com dados malformados.
Divida funções longas e complexas
Funções grandes, com muita lógica, são difíceis de testar. Quando há operações demais, fica difícil testar cada variável de forma eficaz. Se uma função for complexa demais, divida-a em funções menores para testar cada uma separadamente.
Evite conexões de rede e de banco de dados
Os testes unitários devem ser rápidos e leves, mas funções que fazem chamadas de rede ou se conectam a outros aplicativos ou processos demoram para ser executadas. Isso dificulta executar muitas operações ao mesmo tempo e pode deixar o código mais frágil. Você pode usar simulações em testes unitários para simular chamadas de rede ou de banco de dados — assim, é possível testar o restante da função. As conexões reais de rede e de banco de dados podem ser incluídas em outro processo de teste, chamado teste de integração.
Como escrever testes unitários
Agora que vimos algumas boas práticas de testes unitários, você está pronto para escrever seu primeiro teste unitário em JavaScript.
Este tutorial usa o framework Mocha, um dos mais populares para testes unitários. Cada framework de testes tem suas particularidades, mas eles são parecidos o suficiente para que, ao aprender os conceitos básicos, você consiga alternar entre eles sem dificuldade.
Para acompanhar esta demonstração, instale o Node.js no seu computador.
Criar um novo projeto
Comece abrindo uma janela do terminal ou do prompt de comando na pasta de um novo projeto. Em seguida, crie nela um projeto Node.js digitando npm init -y.
Isso cria um arquivo package.json na pasta, permitindo instalar o Mocha como dependência de desenvolvimento usando npm install -D mocha.
Em seguida, abra o arquivo package.json no editor de código e substitua o script de teste temporário por mocha:
Implementar uma classe
Agora, vamos criar um sistema simples de semáforo para testar.
No diretório do projeto, crie um arquivo chamado traffic.js e adicione o código a seguir para criar uma classe TrafficLight:
Esta classe tem quatro partes:
TrafficLight.colors: uma propriedade constante com as cores do semáforo.lightIndex: uma variável que acompanha o índice da cor atual do semáforo.light: uma propriedade da classe que retorna a cor atual do semáforo como uma string.next(): uma função que muda o semáforo para a próxima cor.
Configurar e adicionar nosso primeiro teste unitário
Agora é hora de adicionar testes unitários ao código.
Crie uma pasta chamada test no diretório do projeto. Por padrão, é nela que o Mocha procura os testes unitários. Em seguida, crie um arquivo chamado traffic.test.js dentro da nova pasta de testes.
Em seguida, importe a classe TrafficLight no início do arquivo:
Também vamos usar o módulo assert nos testes, então inclua-o no código:
Com o Mocha, podemos agrupar testes unitários usando a função describe(). Assim, podemos criar um grupo de nível superior para esta classe:
Em seguida, vamos criar alguns testes unitários para validar as cores do semáforo em um subgrupo chamado colors, dentro do grupo TrafficLight:
Neste primeiro teste unitário, podemos verificar se colors tem apenas três estados: verde, amarelo e vermelho. O teste é definido com uma função it() dentro do grupo describe(). Escreva o teste assim:
Agora, vamos executar o teste unitário e ver se ele passa.
Execute npm test na janela do terminal. Se estiver tudo certo, o Mocha exibirá os resultados da execução do teste unitário.

Adicionar mais testes unitários
Nosso projeto já está pronto para executar testes unitários. Podemos adicionar mais testes para garantir que o código esteja funcionando corretamente.
Primeiro, adicione um teste unitário ao grupo colors para validar se as cores do semáforo estão corretas e na ordem certa. Veja uma maneira de implementar esse teste:
Em seguida, teste a função next() para verificar se ela muda corretamente as cores do semáforo. Crie um novo subgrupo e adicione dois testes unitários: um para verificar se as cores mudam na ordem correta e outro para conferir se, depois de red, o ciclo volta para green.
Escreva os testes unitários assim:
Ao executar os testes novamente, veremos que um deles falha. Isso acontece porque há um bug na classe TrafficLight.

Corrigir o bug
Abra novamente o código da classe TrafficLight e localize o comentário dentro da função next() que diz // This is intentionally wrong!
Com nossos testes unitários, sabemos que essa função não está voltando corretamente para green. O código verifica se o valor de lightIndex ultrapassa o número de cores do semáforo, mas o índice começa em 0. Em vez disso, devemos voltar ao início assim que o valor chegar ao número exato de cores. Vamos atualizar o código para redefinir o valor de lightIndex para 0 quando ele for igual ao tamanho da lista de cores do semáforo:
Agora, todos os seus testes unitários devem passar. E o melhor: mesmo que a classe TrafficLight seja refatorada ou bastante modificada, nossos testes unitários vão detectar esse bug antes que ele chegue aos usuários.

Para concluir
Os testes unitários são fáceis de configurar e uma ferramenta eficaz no desenvolvimento de software. Eles ajudam a eliminar bugs logo no início e evitam que voltem. Assim, os projetos ficam mais fáceis de gerenciar e manter, mesmo quando crescem e se tornam mais complexos — especialmente em equipes maiores de desenvolvimento. Testes automatizados como esses também permitem que desenvolvedores refatorem e otimizem o código sem se preocupar se o novo código está funcionando corretamente.
Os testes unitários são uma parte essencial do seu processo de desenvolvimento e são fundamentais para ajudar você a criar aplicativos JavaScript melhores e mais seguros.
Bons testes!
Comece a jogar Capture the Flag
Aprenda a resolver desafios de Capture the Flag assistindo à gravação sob demanda do nosso workshop virtual introdutório.


