Teste de Mutação em PHP: Matando Testes para que Eles Funcionem

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

Seus testes são uma ilusão de segurança?



Imagine: você tem 95% de cobertura de código, todos os testes estão verdes, o CI/CD passa. Você tem certeza de que seu código PHP está protegido contra regressões. Mas será que é realmente assim?



Eu mesmo vivi nessa ilusão por muito tempo, até me deparar com uma situação: o teste passava, embora eu tivesse trocado acidentalmente && por || em uma condição crítica. O teste simplesmente não verificava aquele ramo. A cobertura era de 100%, mas a lógica, não.



Conheça: teste de mutação (mutation testing) — uma técnica que impiedosamente "mata" seus testes para descobrir o quão confiáveis eles realmente são. Neste artigo, vamos abordar como aplicá-la em PHP, usando a poderosa ferramenta Infection, e por que isso muda as regras do jogo.



O que é teste de mutação e por que ele é necessário?



Teste de mutação é uma abordagem na qual pequenas alterações intencionais (mutações) são introduzidas no seu código-fonte. Por exemplo, o operador + é alterado para -, true para false, ou uma linha inteira é removida. Após cada mutação, seus testes são executados.



Se o teste falha — a mutação foi "morta", significa que o teste realmente verifica aquele trecho de código. Se o teste passa — a mutação "sobreviveu". Isso é um sinal de alerta: ou o teste não verifica aquela condição, ou ele foi escrito incorretamente.



Ao contrário da métrica "cobertura de código" (code coverage), que apenas mostra quais linhas foram executadas, o teste de mutação verifica a qualidade das verificações. Uma alta porcentagem de cobertura não é garantia, enquanto o Escore de Mutação (Mutation Score Indicator, MSI) é um indicador real de confiabilidade.



Por que isso é importante para o desenvolvedor PHP?

  • Detecção de testes "mortos" — aqueles que estão sempre verdes, mas não verificam nada.
  • Identificação de lacunas na lógica — por exemplo, condições de contorno negligenciadas.
  • Aumento da confiança durante a refatoração — você sabe exatamente quais testes protegem o código.
  • Economia de tempo — em vez de auditar testes manualmente, você obtém um relatório automático.


Ferramentas para teste de mutação em PHP



O líder no cenário PHP é o Infection (anteriormente conhecido como Humbug). Ele se integra facilmente com PHPUnit e Pest, suporta várias mutações e fornece relatórios visuais.



Outras opções: Humbug (o predecessor, mas menos ativo) e Mutagen (experimental). Vamos nos concentrar no Infection — que é o padrão moderno.



Prática: configurando o Infection no projeto



Vamos instalar o Infection e executá-lo em um exemplo real. Suponha que temos uma classe simples para calcular um desconto:



<?php// src/DiscountCalculator.phpclass DiscountCalculator{    public function calculate(float $price, bool $isPremium): float    {        if ($isPremium) {            return $price * 0.9; // desconto de 10%        }

return $price; }}


E o teste para ela:



<?php// tests/DiscountCalculatorTest.phpuse PHPUnit\\Framework\\TestCase;

class DiscountCalculatorTest extends TestCase{ public function testPremiumDiscount(): void { $calculator = new DiscountCalculator(); $result = $calculator->calculate(100.0, true); $this->assertEquals(90.0, $result); }

public function testRegularPrice(): void { $calculator = new DiscountCalculator(); $result = $calculator->calculate(100.0, false); $this->assertEquals(100.0, $result); }}


Cobertura — 100%. Mas vamos verificar com mutações.



Instalação e execução do Infection



composer require --dev infection/infection./vendor/bin/infection


Após

Blogs

Book Recommendations