Rodei mutation testing numa suíte com 92% de cobertura e o score real foi 41%
Sempre desconfiei de cobertura de teste como métrica de qualidade, mas semana passada botei número na desconfiança.
Peguei um projeto Node com 92% de cobertura no relatório. Selo verde, todo mundo confiante. Rodei um teste de mutação com Stryker e o mutation score voltou 41%.
Mutation testing funciona assim: a ferramenta pega o seu código e introduz um bug de propósito (um "mutante"). Troca > por >=, inverte um if, apaga uma linha, muda + por -. Aí roda a sua suíte inteira contra cada versão estragada. Se algum teste falha, o mutante foi "morto". Se todos passam, o mutante "sobreviveu": você quebrou o código e nenhum teste percebeu.
Rodar é simples num projeto JS/TS:
npm i -D @stryker-mutator/core
npx stryker init
npx stryker run
O relatório lista os mutantes sobreviventes com arquivo e linha. Cada sobrevivente é um teste que executa aquela linha (por isso conta cobertura) mas não verifica o resultado.
O padrão que mais apareceu foi teste sem asserção de verdade:
it('calcula o desconto', () => {
aplicarDesconto(carrinho, cupom) // roda, cobre a linha... e nada
})
Nenhum expect. Se a função não lança exceção, passa. Cobertura sobe, garantia zero. Outro campeão é mock demais: o teste programa a resposta e depois confere a própria resposta que ele mesmo programou.
Regra prática que virou hábito: cobertura serve pra achar código sem NENHUM teste (0% é alerta real). Pra saber se os testes que existem valem alguma coisa, mutation score é bem mais honesto. Um alvo razoável fica em 70-80% nos módulos de regra de negócio; não precisa perseguir 100%, o custo de runtime explode.
Aviso honesto: mutation testing é pesado, porque roda a suíte N vezes. Ligue nos módulos críticos (cálculo, dinheiro, permissão), não no projeto inteiro a cada push no CI.
Se você nunca viu o mutation score da sua suíte, roda uma vez num módulo que mexe com dinheiro. Provavelmente vai doer.
Versão completa (com o lado de negócio da história) no blog: https://revin.com.br/pt/blog/cobertura-de-teste-alta-esconde-bug-em-producao