Analista de dados, pós-graduada em Ciência de Dados e engenheira eletricista de formação.
Um fundador de fintech me mandou um print numa quinta à noite. Era o relatório de testes do fornecedor dele: 92% de cobertura, tudo verde, aquele selo que dá orgulho de colar no README. Na mesma imagem, aberta em outra aba, a tela de checkout do produto congelada. Ele não é cliente da Revin. Tinha me procurado por indicação, querendo uma segunda opinião antes de renovar o contrato com quem construiu aquilo.
A pergunta dele era honesta e desconfortável: como é que 92% de cobertura deixa o checkout cair? A resposta cabe numa frase, e é a origem de metade dos sustos que vejo em produção. Cobertura de teste não mede se o seu software funciona. Mede quantas linhas foram executadas enquanto os testes rodaram. São coisas diferentes, e a distância entre as duas é onde o bug se esconde.

Um teste pode percorrer todo esse componente, imprimir o valor no console e nunca conferir se ele está certo.
Coverage é uma métrica de execução. A ferramenta instrumenta o código, roda a sua suíte e marca cada linha, cada branch e cada função tocada pelo menos uma vez. No fim divide o que foi tocado pelo total e devolve uma porcentagem. Isso serve bem pra uma coisa: achar o código que nenhum teste chega perto. Um trecho com 0% é um alerta de verdade.
O problema é o que ela ignora. A métrica registra que a linha rodou. Se alguém conferiu o resultado daquela linha, ela não faz ideia. Um teste que chama calcularJuros(saldo) e não olha o retorno marca a função como coberta do mesmo jeito. A função rodou. O valor que saiu dela ficou sem revisão. No painel, o verde é idêntico ao de um teste que confere centavo por centavo.
Foi mais ou menos o que encontramos na suíte da fintech. Boa parte dos testes exercitava o código e parava ali, sem nunca perguntar se o resultado batia com o esperado.
Existem três jeitos comuns de um teste ficar oco. Nenhum deles aparece na porcentagem de cobertura:
Os três inflam a cobertura e não seguram nada. Como o número sobe, todo mundo se sente mais seguro. Inclusive o fornecedor, que passa a reportar o 92% como se porcentagem fosse a mesma coisa que qualidade.

Pegar um teste e perguntar 'o que acontece se eu quebrar essa linha de propósito?' revela mais do que qualquer porcentagem no relatório.
Cobertura virou métrica de vendas. Sobe fácil, porque escrever teste sem asserção é rápido. Cabe num número redondo. E impressiona quem não lê código. Para uma agência que fatura por entrega, é o indicador perfeito: cresce quase sozinho e o cliente não tem como contestar de fora.
O incentivo aí é torto. Quando o contrato paga por feature entregue com testes, o fornecedor otimiza pra bater a porcentagem. Prevenir o incidente de produção é outro trabalho, mais chato e mais caro, que ninguém está pagando explicitamente. Não é que estejam mentindo. Estão medindo a coisa fácil e cobrando por ela.
Num squad sênior, o teste é revisado como código de produção. Um pull request que adiciona teste sem asserção não passa no review: ele volta com a pergunta "o que isso está garantindo?". É assim que a gente cuida das suítes dos clientes na Revin, e é o que separa uma cobertura que te protege de uma que só te enfeita. Se ninguém nunca revisou os seus testes com esse rigor, começa por um raio-x honesto do que existe hoje.
Tem uma técnica antiga e pouco usada que mira exatamente esse ponto cego: teste de mutação. A ideia é quase perversa. Uma ferramenta pega o seu código e planta bugs de propósito: troca um > por >=, inverte uma condição, apaga uma linha ou transforma um + em -. Cada versão estragada é um mutante, e a suíte inteira roda contra cada um deles.
A leitura é direta. Se o código foi quebrado e nenhum teste reclamou, aquele teste não estava protegendo nada: o mutante sobreviveu. O que importa deixa de ser quantas linhas você cobre e passa a ser quantos desses bugs plantados a sua suíte consegue matar. Ferramentas como Stryker, no mundo JavaScript e TypeScript, e PIT, em Java, fazem isso e devolvem um mutation score.
Rodamos o Stryker naquela suíte de 92%. O mutation score deu 41%. Traduzindo: mais da metade dos bugs que plantamos de propósito passou reto pelos testes verdes. Esse número oscila conforme a ferramenta e o que você manda ela mutar, admito. Não trato 41% como lei da física. Mas mesmo cortando uma margem generosa, a conclusão não muda: a suíte confortável cobria bastante e, na hora de segurar um bug real, deixava passar. Esse é o tipo de leitura que a gente faz nos primeiros dias com um cliente, e alguns viram caso publicado depois.
Se você é fundador, não peça a porcentagem de cobertura. Ela vem alta e não te conta nada. Pergunte outra coisa pro seu time ou pro seu fornecedor: o que acontece com a suíte se alguém quebrar uma regra de negócio de propósito? Se a resposta for silêncio, ou um 'a gente confia nos noventa e poucos por cento', você já tem o diagnóstico.
Vou ser justa. Nem todo projeto precisa disso. Um site institucional de cinco páginas nunca vai montar teste de mutação, e está ótimo assim: ali cobertura alta já resolve, e contratar um squad sênior seria desperdício do seu dinheiro. Agora, qualquer coisa que mexe com dinheiro, com dado sensível ou com um fluxo que derruba a operação inteira quando cai, o número bonito sozinho é teatro.
O fundador da fintech não trocou de fornecedor por raiva. Trocou porque, pela primeira vez, alguém sentou com ele e mostrou na prática o quanto aquela suíte confortável realmente defendia o produto dele. Era pouco. Se você desconfia que a sua cobertura está mais pra enfeite, o primeiro passo é olhar de verdade o que a sua suíte garante hoje, e esse raio-x cabe numa conversa.
5 min de leitura
Conteúdos do Artigo: