Pular para o conteúdo
Development

Escrevendo testes que checam a coisa certa

Por Victor Da Luz
railsrubytestingdev-logblog-manager

Fechei um item pequeno do backlog hoje: dois arquivos com lacunas reais de cobertura vindas de uma auditoria anterior. Um job nunca tinha sido testado, e um cliente HTTP tinha zero testes. Não é um trabalho empolgante à primeira vista, mas virou um bom lembrete sobre a diferença entre um teste que passa e um teste que realmente verifica alguma coisa.

O que eu construí

Para o cliente do GitHub, eu precisava de um jeito de testar chamadas HTTP sem bater na API real. Em vez de inventar algo novo, fui ver como o código já resolve isso, e encontrei, num cliente irmão para um serviço diferente. Ele recebe um objeto opcional que pode substituir a conexão HTTP real, caindo de volta pra conexão de verdade em produção. Copiei a forma exata: mesmo nome de parâmetro, mesma lógica de fallback, mesmo comentário. Quando um padrão já existe e funciona, seguir ele vale mais do que uma alternativa criativa.

Para o job, segui o padrão que todo outro teste de job na suíte já usa: trocar a classe da qual ele depende por uma falsa, temporariamente, e devolver a real quando o teste termina. Direto ao ponto, e bateu com outros quatro arquivos fazendo a mesma coisa.

O que me surpreendeu

Os dois conjuntos de testes passaram limpos na primeira rodada. Isso deveria ter sido tranquilizador. Em vez disso, quando rodei uma revisão sobre o diff, ela fez uma pergunta mais útil do que «isso passa», fez «o que esse teste realmente pegaria».

Acontece que: não muita coisa, em alguns pontos. O dublê do meu teste de job não ligava com quais argumentos ele era chamado, só que fosse chamado. Se uma mudança futura silenciosamente deixasse de passar uma das quatro coisas que o job repassa (digamos, esquecesse de passar o horário de agendamento), todo teste continuaria passando, porque nada estava checando. Mesma história do lado do cliente HTTP: a conexão falsa ignorava a requisição real sendo montada e sempre devolvia uma resposta enlatada. Um bug que bagunçasse o caminho da URL, ou derrubasse o cabeçalho de autorização, passaria batido.

Os dois foram rápidos de corrigir depois de nomeados. Fiz os dublês capturarem com o que foram chamados, e depois adicionei asserções contra isso. Para o job: ele passa o post certo e os argumentos certos pra coisa que realmente fala com o Postiz? Para o cliente: ele monta uma requisição pro caminho certo com o cabeçalho certo? Mudanças pequenas, mas são a diferença entre «isso não quebra» e «isso faz o que deveria fazer».

A revisão também pegou algo mais chato e inegociável: eu tinha copiado um comentário daquele cliente irmão ao pé da letra, travessão incluído. A regra global de estilo diz que não pode travessão em lugar nenhum, incluindo comentários de código. Correção fácil, mas um bom lembrete de que copiar um padrão significa copiar seus defeitos também, a menos que você esteja prestando atenção.

Última coisa: duas linhas de setup que pareciam necessárias não eram. Uma configurava uma chave de API que o mock do teste tornava irrelevante, o caminho de código real que a lê nunca roda quando você substituiu o objeto inteiro ao qual ela pertence. Não deletei por palpite; removi, rodei os testes de novo, vi que continuavam passando, e só então confiei que era seguro deixar de fora.

O que vem a seguir

Nada pendente nesse. A lição recorrente do trabalho de hoje: uma suíte de testes verde diz que o código que você escreveu não quebrou nas condições exatas para as quais você o escreveu. Se ele realmente pegaria uma regressão de verdade é uma pergunta separada, e vale a pena fazer explicitamente em vez de presumir que a resposta é sim.

Leitura relacionada

Você também pode achar útil

Proton

Proton VPN

VPN comercial com filtragem NetShield e interruptor de desligamento automático.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais
Proton

Proton Mail

E-mail criptografado de ponta a ponta, com arquitetura de acesso zero.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais
Proton

Proton Drive

Armazenamento em nuvem criptografado, da equipe por trás do Proton Mail.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais