Teste de Mutação em TypeScript: Quebrando o Código para Melhorá-lo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Tem certeza de que seus testes realmente funcionam?

\n\n

Imagine: você tem 95% de cobertura de código, todos os testes estão verdes, o CI/CD passa sem erros. A equipe está satisfeita, o gerente está tranquilo. Mas um dia, um bug aparece em produção. Você abre o código, olha para os testes e percebe: eles apenas verificam se a função retorna um número, mas não verificam o valor dele. Ou pior — o teste foi escrito de forma que passa em qualquer cenário.

\n\n

Situação familiar? Bem-vindo ao mundo onde a porcentagem de cobertura é apenas um número, não uma garantia de qualidade. É aqui que entra o teste de mutação (mutation testing) — uma metodologia que realmente faz seus testes sofrerem e provarem seu valor.

\n\n

Neste artigo, vamos explorar como implementar o mutation testing em um projeto TypeScript usando Stryker, e por que isso pode se tornar sua nova ferramenta favorita (ou uma nova fonte de dor de cabeça).

\n\n

O que é teste de mutação em palavras simples?

\n\n

Teste de mutação é quando você pega seu código, introduz intencionalmente pequenos erros (mutações) e verifica se seus testes falham. Se os testes não falham — significa que você está testando incorretamente. Se falham — você está de parabéns, mas o mutante foi eliminado.

\n\n

Parece sádico? Talvez. Mas funciona. Imagine que você é um engenheiro de QA que secretamente entrou no código e substituiu === por ==, > por < ou removeu uma chamada de função. Um bom teste deve perceber isso. Um teste ruim vai deixar passar.

\n\n

Em TypeScript, com sua tipagem forte, o teste de mutação é especialmente útil: ele captura casos onde os tipos estão corretos, mas a lógica não está.

\n\n

Por que a cobertura de código comum (code coverage) é uma ilusão?

\n\n

Suponha que você tenha uma função:

\n\n
function calculateDiscount(price: number, isPremium: boolean): number {\n  if (isPremium) {\n    return price * 0.8;\n  }\n  return price;\n}
\n\n

E um teste:

\n\n
test('returns number', () => {\n  const result = calculateDiscount(100, true);\n  expect(typeof result).toBe('number');\n});
\n\n

Cobertura? 100%. Teste? Passa. E se substituirmos price * 0.8 por price * 0.5? O teste ainda passará — ele só verifica o tipo, não o valor. Aqui está a falsa sensação de segurança.

\n\n

O teste de mutação destacará essa mutação e dirá: "Ei, seu teste não percebeu que eu mudei o desconto!". E você terá que escrever uma verificação adequada.

\n\n

Como o mutation testing funciona em TypeScript: passo a passo

\n\n

Todo o processo pode ser dividido em três etapas:

\n\n
    \n
  1. Geração de mutantes — a ferramenta copia seu código e faz uma alteração de cada vez. Por exemplo, troca && por || ou remove uma chamada de método.
  2. \n
  3. Execução dos testes — para cada mutante, seus testes são executados.
  4. \n
  5. Análise dos resultados — se os testes falharam, o mutante foi "morto". Se não, ele "sobreviveu", e isso é uma zona de risco.
  6. \n
\n\n

A principal métrica é o mutation score (porcentagem de mutantes mortos). 100% é o ideal, mas na prática, 80-90% já é excelente.

\n\n

Ferramenta nº 1 para TypeScript: Stryker

\n\n

No mundo TypeScript e JavaScript, o rei do teste de mutação é o Stryker (StrykerJS). Ele é rápido, funciona com Jest, Vitest, Mocha e até com testes de navegador. Configura-se em 5 minutos.

\n\n

Vamos instalar:

\n\n
npm install --save-dev @stryker-mutator/core @stryker-mutator/jest-runner
\n\n

Criaremos o arquivo de configuração stryker.conf.js:

\n\n
// stryker.conf.js\nexport default {\n  mutate: ['src/**/*.ts', '!src/**/*.spec.ts'], // o que mutar\n  testRunner: 'jest',\n  reporters: ['html', 'clear-text', 'progress'],\n  jest: {\n    projectType: 'custom',\n    configFile: 'jest.config.ts',\n  },\n  concurrency: 4, // quantos mutantes                

Blogs

Book Recommendations