O que é teste de mutação? (Exemplo)
⚡ Resumo Inteligente
O teste de mutação introduz deliberadamente pequenas falhas no código-fonte e, em seguida, executa o conjunto de testes existente em cada versão com falha, verificando se esses testes são suficientemente robustos para detectar a alteração.
O que é teste de mutação?
Teste de mutação O teste de mutação é um tipo de teste de software no qual certas instruções do código-fonte são alteradas, ou modificadas, para verificar se os casos de teste conseguem encontrar erros no código-fonte. O objetivo do teste de mutação é garantir a qualidade dos casos de teste em termos de robustez, de modo que eles falhem quando confrontados com o código-fonte modificado.
A alteração feita em um programa mutante deve ser extremamente pequena, para que não afete o objetivo geral do programa. O teste de mutação também é chamado de estratégia de teste baseada em falhas, pois envolve a criação deliberada de uma falha no programa. É uma forma de Branco Box Testes que é aplicado principalmente durante Teste de Unidade.
O teste de mutação foi proposto em 1971 em um artigo acadêmico de Richard Lipton e formalizado em 1978 no artigo "Dicas sobre Seleção de Dados de Teste" de DeMillo, Lipton e Sayward. Perdeu força devido ao custo computacional da época, mas desde então recuperou terreno em linguagens como... Java, C#, Python, JavaScript e XML.
Como executar testes de mutação?
A seguir, apresentamos os passos para executar o teste de mutação, também conhecido como análise de mutação:
Passo 1: As falhas são introduzidas no código-fonte do programa através da criação de várias versões chamadas mutantes. Cada mutante deve conter uma única falha, e o objetivo é fazer com que a versão mutante falhe, demonstrando assim a eficácia dos casos de teste.
Passo 2: Os casos de teste são aplicados tanto ao programa original quanto ao programa mutante. Caso de teste deve ser adequado e é ajustado para detectar falhas em um programa.
Passo 3: Compare os resultados do programa original com os do programa mutante.
Passo 4: Se o programa original e o programa mutante gerarem saídas diferentes, então o mutante é eliminado pelo caso de teste. Portanto, o caso de teste é suficientemente bom para detectar a mudança entre o programa original e o mutante.
Passo 5: Se o programa original e o programa mutante gerarem a mesma saída, o mutante permanece ativo. Nesses casos, é necessário criar casos de teste mais eficazes que eliminem todos os mutantes.
O diagrama abaixo tracSão os mesmos cinco passos, desde o programa original, passando pela geração de mutantes, até o veredito de morte ou sobrevivência.
Como criar programas mutantes?
Uma mutação nada mais é do que uma única alteração sintática feita em uma instrução de um programa. Cada programa mutante deve diferir do programa original por exatamente uma mutação.
| Programa Original | Programa Mutante |
| Se (x>y) Imprima “Olá” Outro Imprima “Oi” |
Se (x Imprima “Olá” Outro Imprima “Oi” |
No par de exemplos acima, apenas o operador de comparação foi alterado; contudo, um caso de teste em que x é maior que y agora imprime "Hi" em vez de "Hello". A ilustração mostra essa alteração sintática.
O que mudar em um Programa Mutante?
Existem diversas técnicas que podem ser usadas para gerar programas mutantes. As três famílias abaixo abrangem a maioria dos operadores de mutação que acompanham as ferramentas.
| Operaoperadores de substituição nd | Operadores de modificação de expressão | Operadores de modificação de instruções |
| Substitua o operando por outro operando (x por y, ou y por x) ou por um valor constante. | Substituir um operador ou inserir um novo operador em uma instrução de programa. | As instruções programáticas são modificadas para criar programas mutantes. |
| Exemplo: If(x>y) substitua os valores x e y Se(5>y) substitua x pela constante 5 |
Exemplo: Se(x==y) Podemos substituir == por >= e obter o programa mutante como If(x>=y) e inserção de ++ na instrução Se(x==++y) |
Exemplo: Exclua a parte else em uma instrução if-else Apague toda a instrução if-else para verificar como o programa se comporta. |
Alguns exemplos de operadores de mutação:
- Substituição da etiqueta GOTO
- Substituição da declaração de retorno
- Exclusão de declaração
- Inserção de operador unário (como – e ++)
- Substituição do conector lógico
- Substituição de nome de array comparável
- Remover a parte "else" de uma instrução if-else.
- Adicionar ou substituir operadores
- Substituição de declaração alterando os dados
- Modificação de dados para as variáveis
- Modificação de tipos de dados no programa
OperaOs tors que tocam uma condição de contorno são os que sobrevivem com mais frequência, portanto, os resultados da mutação frequentemente apontam para lacunas em análise de valor limite.
Tipos de testes de mutação
In Engenharia de SoftwareOs testes de mutação são fundamentalmente categorizados em três tipos: mutação de declaração, mutação de valor e mutação de decisão.
- Mutação de declaração – uma declaração é recortada, colada ou excluída, portanto, o resultado pode ser a remoção de algumas linhas de código.
- Mutação de valor – os valores dos parâmetros primários e das constantes são modificados, por exemplo, alterando um limite de loop ou um limiar.
- Mutação de decisão – as instruções de controle são alteradas, por exemplo, flipping um operador relacional ou negação de uma condição.
As ferramentas agrupam seus operadores sob esses três títulos, de modo que a família que produziu um mutante sobrevivente indica ao testador qual tipo de asserção está faltando. Um mutante de decisão sobrevivente geralmente marca um ramo não testado, que se sobrepõe a teste de loop.
Automação de testes de mutação
O teste de mutação é extremamente demorado e complexo de executar manualmente, por isso é aconselhável usar ferramentas de automação, que também reduzem custos. Uma ferramenta de mutação compila os mutantes, agenda as execuções, registra qual mutante cada teste com falha eliminou e relata a pontuação.
Lista de ferramentas disponíveis:
- Stryker — uma estrutura de teste de mutação de código aberto com edições para JavaRoteiro e TypeScript (StrykerJS), C# e .NET (Stryker.NET) e Scala (Stryker4s).
- PIT, também escrito PITest — um sistema de teste de mutações para Java e a JVM que modifica o bytecode compilado e se integra ao Maven e Gradle constrói ao lado de JUnit.
Ambas são executadas como uma etapa de compilação, portanto pertencem ao mesmo grupo. integração contínua oleoduto como o resto do teste de automação diante.
Pontuação de mutação
A pontuação de mutação é definida como a porcentagem de mutantes mortos em relação ao número total de mutantes.
Pontuação de mutação = (mutantes mortos / número total de mutantes) * 100
A fórmula é mostrada abaixo no formato em que a maioria das ferramentas a apresenta.
Os casos de teste são descritos como adequados para mutação quando a pontuação atinge 100%. Na prática, o denominador deve excluir mutantes equivalentes — mutantes cuja sintaxe alterada se comporta exatamente como a original, de modo que nenhum teste consegue eliminá-los. As ferramentas, portanto, reportam os mutantes eliminados divididos pelo número de mutantes não equivalentes eliminados mais sobreviventes, e permitem que o testador sinalize os equivalentes.
Resultados experimentais demonstraram que o teste de mutação é uma maneira eficaz de medir a adequação dos casos de teste. A principal desvantagem é o custo de geração dos mutantes e de execução de cada caso de teste contra cada um deles.
Teste de mutação vs. Code Global
Alto cobertura de teste Não comprova testes robustos. A cobertura de linhas e ramificações registra quais instruções foram executadas, não se algo foi verificado posteriormente; portanto, um teste que chama um método e não verifica nada ainda conta como coberto. O teste de mutação preenche essa lacuna, pois um mutante só é descartado quando uma asserção falha de fato.
| Aspecto | Code cobertura | Pontuação de mutação |
| O que mede | Quais linhas ou ramificações os testes executaram? | Quais falhas injetadas os testes detectaram? |
| Sensível a afirmações | Não — um teste com zero asserções ainda adiciona cobertura. | Sim — um mutante sobrevive quando nenhuma afirmação falha. |
| Custo de uma execução | Um teste instrumentado | Um teste por mutante sobrevivente, até agora muito mais lento. |
| Uso típico | Um portão rápido em cada commit | Uma verificação periódica mais aprofundada dos módulos críticos. |
| Modo de falha | Cobertura de 100% sem nenhuma verificação real. | Mutantes equivalentes que nunca podem ser mortos. |
As duas métricas são complementares. A cobertura nomeia o código que nunca foi alcançado; a pontuação de mutação nomeia o código alcançado que nunca foi verificado. Ambas alimentam o mesmo objetivo. processo de gerenciamento de defeitos, juntamente com medidas como densidade de defeitos.
Vantagens do teste de mutação
A seguir estão as vantagens do teste de mutação:
- É uma abordagem poderosa para obter alta cobertura do programa fonte.
- Ele testa o próprio conjunto de testes, algo que nenhum outro faz. técnica de teste de software faz isso diretamente.
- Os testes de mutação proporcionam um bom nível de detecção de erros para o desenvolvedor de software.
- O método descobre ambiguidades no código-fonte e tem a capacidade de expor falhas que execuções comuns jamais alcançariam.
- Os mutantes sobreviventes são passíveis de ação: cada um deles indica uma linha específica e uma alteração específica que o conjunto de testes não conseguiu detectar.
- Os clientes se beneficiam desses testes ao receberem um sistema mais confiável e estável.
Desvantagens do teste de mutação
Por outro lado, as desvantagens dos testes de mutação são as seguintes:
- Os testes de mutação são extremamente caros e demorados, pois exigem a geração e compilação de um grande número de programas mutantes.
- Como é um processo demorado, pode-se afirmar que esse teste não pode ser realizado sem uma ferramenta de automação.
- Cada mutante é submetido ao mesmo número de casos de teste que o programa original, portanto, uma grande população de mutantes deve ser executada em todo o conjunto de testes.
- Os mutantes equivalentes não podem ser eliminados por nenhum teste, e a distinção entre eles e os sobreviventes genuínos geralmente requer análise manual.
- Como o método altera o código-fonte, ele não é aplicável a Preto Box Testes.
Quando usar testes de mutação
O perfil de custos acima significa que o teste de mutação raramente é executado em toda a base de código a cada commit. Ele se paga quando uma falha não detectada é custosa e o código em teste é pequeno o suficiente para sofrer mutações rapidamente.
- Lógica crítica para a segurança ou lógica financeira — Cálculo de pagamentos, regras fiscais e verificações de autorização, onde uma resposta errada silenciosa é pior do que uma falha.
- Suítes com cobertura suspeitamente alta. — quando a cobertura está próxima de 100%, mas ainda assim defeitos passam despercebidos.
- Código legado sendo refatorado — Os resultados das mutações revelam se os testes existentes seriam capazes de detectar uma regressão.
- Bibliotecas e componentes compartilhados — uma falha em um reutilizado componente multiplica-se para cada pessoa que liga.
- Equipes praticando desenvolvimento dirigido por teste — a pontuação verifica se os testes escritos inicialmente têm um impacto real.
Geralmente não vale a pena executar testes em protótipos descartáveis, em código de integração frágil ou código gerado sem lógica de ramificação, ou em suítes dominadas por testes lentos. testes de integração que já levam horas para uma única passagem.
Portanto, a maioria das equipes limita a execução aos arquivos alterados, define um limite para os módulos relevantes e deixa que o restante da equipe execute as tarefas. teste de regressão suíte carrega o resto do ciclo de vida de teste de software.



