Executando verificação de segurança...
2

(Pergunta) Quando devo usar testes?

Estava tranquilo fazendo meu CRUD. Uma Todo List que pretendo personalizar para meu irmão. Por enquanto está bem genérica e não tenho certeza de até onde isso pode evoluir.
Quando o grosso já estava feito e funcionando comecei a pensar "Bom, e agora? Continuo criando features feito louco ou paro um pouco para consolidar meu progresso?".

Estou falando sobre testes.
Sempre que fazia uma mudança nas rotas ou nas funções em /models tinha que sair testando manualmente todas as funcionalidades.
Posso fazer testes automatizados para as funções antigas, que vão me avisar se eu quebrar uma função antiga, na teoria. Assim posso focar nas coisas novas sem ter medo de ser feliz.

Arreganhei as mangas e fui pesquisar sobre testes de unidade, de integração, end to end, jest, supertest, etc.
Basicamente o que eu tinha para testar na hora eram as rotas de um CRUD, que chamavam funções que faziam verificações simples com a requisição e chamavam outra função que fazia a query para o banco de dados.
Totalizando três camadas a serem testadas.

Aprendi o básico da sintaxe de Jest:

  • describe()
  • test()
  • beforeEach()
  • beforeAll()

Tive algumas dificuldades configurando ele. Estava dando um problema sobre CommonJS e ES Modules. Resolvi alterando o comando dentro do package.json de "test": "jest" para "test": "NODE_OPTIONS=\"--experimental-vm-modules\" jest". Também havia a opção de usar um tal de babel para "transpilar"(??) meu código para CommonJS.
Sinceramente, só queria avançar, estava confuso com o funcionamento do Jest e não queria instalar mais uma biblioteca.

Em seguida fui pesquisar sobre mock para testar cada camada separadamente. Esse foi o principal motivo para fazer esse post. Tive diversos problemas para substituir as funções que fazem query para o BD por funções mockadas. Acontecia por causa que as funções de /models eram importadas pelo arquivo de teste antes de mockar as funções. Assim o mock não funcionava. Depois de perder quase uma tarde inteira lendo a documentação achei a solução pro meu problema.
Agora, livre para escrever meus testes em paz, depois de fazer os primeiros testes com ajuda da IA fui entendendo melhor a lógica por trás de mockar funções e como isso realmente funcionava (a lógica de dizer o que a função mockada vai retornar para a função que você está testando).

Mesmo tendo apenas duas tabelas no meu banco de dados, ainda foi um processo bem repetitivo e aparentemente inútil. Tive que fazer tantos mocks que cheguei a perder de vista o que estava realmente testando. E isso se deve a lógica simples das funções que estava testando.

Por exemplo, na função a seguir há uma validação mínima seguida de uma requisição ao banco de dados:

export async function login(req, res) {
  const { email, password } = req.body;
  if (!email || !password) return res.status(400).json({ error: 'Email e senha necessários' });
  try {
    const user = await findUserByEmail(email);
    if (!user) return res.status(401).json({ error: 'Email ou senha inválidos' });
    const match = await bcrypt.compare(password, user.password);
    if (!match) return res.status(401).json({ error: 'Email ou senha inválidos' });
    const token = jwt.sign({ id: user.id, email: user.email }, process.env.JWT_SECRET, { expiresIn: '7d' });
    res.json({ token });
  } catch (err) {
    res.status(500).json({ error: 'Erro ao fazer login' });
  }
}

Com certeza tirei vários aprendizados fazendo os testes. Passar por todos os possíveis fluxos de execução e lidar com cada um foi um deles.

Fora lidar com cada resposta possível da função, praticamente não tinha nada a ser testado.

Terminei com a sensação que foi um tempo desperdiçado. Imagino que testes se paguem no longo prazo, conforme o sistema cresce e fica mais complicado, você mantém tudo sobre controle.
Você tem um alerta para saber quando algo para de funcionar sem ter que manter o código inteiro na "RAM" junto com qual código interage com qual.

É essa a lógica por trás dos testes? Ou eu ainda estou perdendo de vista algo importante?

Carregando publicação patrocinada...
2

Definitivamente o ganho é no médio/longo prazo, no curto prazo é facilmente confundido com perda de tempo (principalmente por superiores não técnicos na empresa). Respondendo a pergunta do título, a resposta é sempre. Existe uma frase do uncle Bob que diz que um código que não é testado é um código sem valor. Recomendo fortemente procurar sobre o TDD (test driven development) e de quebra vou te recomendar o livro "O codificador limpo" (não confundir com código limpo) que é de onde vem a frase que citei do uncle bob

2

Só uma complementação para as pessoas q não sabem mto sobre testes não confundirem, TDD não é sinônimo de testes de unidade e sim uma forma de programar baseado em testes, onde os testes são criados primeiros e depois vem o código de produção.

Eu por exemplo, já trabalhei no estilo TDD puro (na época eu era fullstack), mas para quem é mais baseado em telas (front e mobile, por exemplo), TDD é massante demais, pois nosso foco principal é tela e tela se inicia pelo design. Por isso sempre faço primeiro os códigos, depois os testes, pois pelo menos pra mim isso é o q funciona.

Mas não significa q não use TDD. Eu uso normalmente em pequenos códigos e especializados voltados pra regra de negócio dentro do mobile, pois nesses códigos são simples usar TDD. Primeiro vc define as entradas e os resultados (ou seja, cria o teste) de um tal método, depois vc cria o código com base nesses testes, ou seja, TDD. Claro q resumi bem aqui, assim como o felprangel, recomendo leia sobre TDD q compensa bte ver como funciona essa forma de programar.
Eu aprendi sobre essas diferenças depois de ler Test-Driven Development do Mauricio Aniche, mas imagino q qqr livro possa ensinar isso. O legal q nesse livro mostrou coisas mais complexas como qndo expandir o código em novas classes e tals, mas nunca consegui chegar nesse nível via TDD, prefiro do modo tradicional, codificar primeiro e depois aplicar testes neles.

Só mais uma coisa para qm está iniciando nisso, uma coisa q acredito é q não existe o certo e o errado de como fazer os testes, o q existe é, se vc não fizer testes hj, vc pode pagar o preço no futuro.