Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Stryker no Node.js

Atualizado em: 25 de setembro de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

StrykerJS é uma ferramenta de testes de mutação para JavaScript e TypeScript. Em vez de medir apenas quais linhas foram executadas, ela modifica pequenas partes do código e verifica se os testes detectam o comportamento incorreto. Se uma mutação sobrevive, existe uma lacuna na suíte, uma asserção fraca ou código sem efeito observável.

Exemplo: o código usa > e Stryker troca por >=. Se todos os testes continuam passando, talvez o caso de limite nunca tenha sido validado. Mutation testing responde à pergunta: os testes realmente impedem regressões?

Por que cobertura não basta

Uma linha pode ser executada sem que o resultado seja verificado:

export function desconto(valor, vip) {
  if (vip) return valor * 0.8;
  return valor;
}

Um teste que apenas chama desconto(100, true) cobre a linha, mas não garante que o desconto seja 20%. Stryker pode alterar 0.8 para outro valor; a mutação sobreviverá se não houver asserção.

Instalação

npm install -D @stryker-mutator/core
npx stryker init

O assistente pergunta framework de teste, reporter e configuração. Para Node Test Runner, Jest, Vitest, Mocha e outros, instale o runner correspondente quando necessário.

Configuração inicial

Crie stryker.config.mjs:

export default {
  mutate: [
    'src/**/*.js',
    '!src/**/*.test.js',
    '!src/generated/**',
  ],
  testRunner: 'command',
  commandRunner: {
    command: 'npm test',
  },
  reporters: ['clear-text', 'progress', 'html'],
  coverageAnalysis: 'perTest',
  thresholds: {
    high: 80,
    low: 60,
    break: 55,
  },
};

O runner command é genérico. Integrações específicas costumam ser mais rápidas porque permitem selecionar testes relacionados.

Executando

npx stryker run

O processo executa primeiro os testes sem mutação. Depois cria mutantes, roda testes e classifica os resultados.

Status dos mutantes

  • Killed: um teste falhou e matou a mutação;
  • Survived: testes passaram; exige investigação;
  • No coverage: nenhum teste executou o mutante;
  • Timeout: mutação causou execução lenta ou infinita;
  • Compile error: mutação gerou código inválido;
  • Ignored: mutante excluído por configuração;
  • Runtime error: processo falhou antes de uma asserção útil.

Mutation score

A pontuação geralmente considera mutantes mortos sobre mutantes válidos. Uma porcentagem alta sugere testes sensíveis, mas não é objetivo absoluto. Código gerado, defensivo ou impossível de observar pode produzir mutantes equivalentes.

Use o score como indicador e tendência. Não escreva testes inúteis apenas para alcançar 100%.

Mutadores comuns

Stryker altera:

  • operadores aritméticos;
  • comparações;
  • booleanos;
  • condições;
  • strings e números;
  • retornos;
  • expressões opcionais;
  • blocos e chamadas.

Cada alteração representa uma possível falha introduzida por um desenvolvedor.

Exemplo de mutante sobrevivente

export function podeComprar(saldo, preco) {
  return saldo >= preco;
}

Teste insuficiente:

test('permite quando há saldo', () => {
  assert.equal(podeComprar(100, 50), true);
});

Se >= for trocado por >, o teste passa. Adicione limite:

test('permite quando saldo é igual ao preço', () => {
  assert.equal(podeComprar(50, 50), true);
});

Mutantes equivalentes

Algumas mudanças não alteram comportamento observável. Exemplo: uma condição redundante ou valor que nunca chega ao consumidor. Esses mutantes não podem ser mortos por um teste legítimo.

Antes de adicionar um teste, confirme se a mutação realmente muda a saída, efeito ou erro público. Caso seja equivalente, ignore de forma documentada ou refatore o código.

Selecionando arquivos

Não comece pelo repositório inteiro. Escolha módulos críticos:

mutate: [
  'src/domain/**/*.ts',
  'src/security/**/*.ts',
  '!src/**/*.d.ts',
]

Priorize regras de negócio, cálculo, autorização e transformações de dados. Controllers simples e arquivos gerados podem ter menor retorno.

Performance

Mutation testing executa muitos testes. Para controlar duração:

  • use runner específico;
  • ative análise por teste;
  • mutacione somente arquivos alterados ou críticos;
  • configure workers paralelos;
  • elimine testes lentos;
  • use execução incremental;
  • rode suíte completa em agenda noturna.

Workers

Configure concorrência:

concurrency: 4

Mais workers aumentam CPU e memória. Em CI compartilhado, excesso pode tornar tudo mais lento.

Timeouts

Uma mutação pode remover condição de parada. Stryker usa fator e margem sobre a duração normal:

timeoutFactor: 1.5,
timeoutMS: 5000

Não aumente indiscriminadamente. Timeouts frequentes podem indicar testes instáveis ou mutações em loops sensíveis.

TypeScript

Stryker suporta TypeScript por transformação e plugins. Mantenha typecheck separado:

npm run typecheck
npx stryker run

Testes de mutação não substituem o compilador. Algumas mutações podem violar tipos antes de executar; configure o checker quando necessário.

Jest ou Vitest

Use plugin correspondente para aproveitar seleção e cobertura:

npm install -D @stryker-mutator/jest-runner
export default {
  testRunner: 'jest',
  jest: {
    projectType: 'custom',
    configFile: 'jest.config.js',
  },
};

Para Vitest, use o runner mantido e alinhe a versão suportada.

Node Test Runner

Quando não houver integração específica adequada, use command runner. Organize testes para que o comando seja determinístico e termine corretamente.

Relatório HTML

O reporter HTML mostra arquivo, linha, mutação e testes executados. Publique o relatório como artefato do CI, sem expor código privado em locais públicos.

Thresholds

thresholds: {
  high: 85,
  low: 70,
  break: 65,
}

break faz o processo falhar abaixo do limite. Comece com o nível atual e aumente gradualmente. Um limite impossível incentiva ignores indevidos.

Baseline e incremental

Recursos incrementais evitam reprocessar mutantes cujo código e testes não mudaram. Armazene resultados entre execuções conforme a configuração e invalide o cache quando versões, config ou ambiente mudarem.

CI em pull requests

Uma estratégia prática:

  1. unit tests em todos os PRs;
  2. mutação somente nos arquivos alterados;
  3. relatório completo em branch principal;
  4. execução completa noturna;
  5. tendência registrada em dashboard.

Stryker Dashboard

O dashboard armazena mutation score por branch e commit. Proteja token e avalie política de envio de dados para projetos privados.

Desabilitando mutantes

É possível ignorar trecho específico, mas documente a razão:

// Stryker disable next-line StringLiteral: mensagem não faz parte do contrato
throw new Error('Falha interna');

Não use comentários para esconder testes fracos. Revise ignores periodicamente.

Testes de integração

Mutacionar código que inicia bancos e containers pode ser muito caro. Separe lógica de domínio para testes rápidos e mantenha poucos mutantes em camadas integradas.

Interpretação correta

Um mutante sobrevivente pode indicar:

  • falta de teste;
  • asserção insuficiente;
  • código morto;
  • comportamento não observável;
  • mutante equivalente;
  • teste selecionado incorretamente.

A ação não é sempre “adicionar teste”. Às vezes é remover ou simplificar código.

Erros comuns

  • rodar todo o monorepo no primeiro dia;
  • buscar 100% sem análise;
  • ignorar muitos mutantes;
  • usar testes lentos e instáveis;
  • não fixar versões de plugins;
  • confundir cobertura com mutation score;
  • não revisar mutantes equivalentes.

Fluxo recomendado

Comece por um módulo crítico, estabeleça baseline, analise sobreviventes, fortaleça asserções e expanda gradualmente. Combine com Node Test Runner, integração real em Testcontainers, contratos em Pact no Node.js e CI em GitHub Actions.

Consulte a documentação oficial do StrykerJS e a lista oficial de mutadores suportados.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita