Teste de mutação 
Luís Armando Bianchin 
Consultant Developer
Agenda 
● Problema 
● O que é teste de mutação? 
● Exemplos 
● Por que? 
● Ferramentas 
● Uso num projeto real
Problema 
● Os testes estão corretos? 
● Cobrem todos requisitos? 
● Qual a qualidade dos testes?
Problema 
● Cobertura de linhas apenas verifica execução de código 
● 100% de cobertura != boa suite de testes 
● Apenas testes "happy path" ou fáceis 
● Código apenas parcialmente testado
Os testes são 
capazes de detectar 
falhas?
Origem 
● Proposto na Academia ~ 1978 
● Yale University e Georgia Institute of technology 
● Hipótese do programador competente 
○ Programas quase perfeitos 
○ Falhas pequenas 
○ Pequenas alterações para correção
O que é teste de mutação? 
● Introduz falhas (mutações) na implementação 
○ Alterações semânticas 
● Roda os testes 
● Os testes realmente quebraram? 
● Mutações mortas ou vivas? 
● Os testes identificaram as falhas?
Exemplo 
Mutação de troca de && para || 
if (a && b) { 
c = 1; 
} else { 
c = 0; 
} 
if (a || b) { 
c = 1; 
} else { 
c = 0; 
}
Efeito colateral não testado 
@Test 
public void 
shouldFailWhenGivenFalse() { 
assertEquals("FAIL", foo(false)); 
} 
@Test 
public void 
shouldBeOkWhenGivenTrue() { 
assertEquals("OK", foo(true)); 
} 
public static String foo(boolean b) { 
if ( someThing(i) ) { 
doImportantBusinessLogic(); 
return "OK"; 
} 
return "FAIL"; 
} 
Não verifica se doImportantBusinessLogic foi chamado
Teste de limite incompleto 
@Test 
public void 
shouldReturnBarWhenGiven1() { 
assertEquals("bar", foo(1)); 
} 
@Test 
public void 
shouldReturnFooWhenGivenMinus1() { 
assertEquals("foo", foo(-1)); 
} 
public static String foo(int i) { 
if ( i >= 0 ) { 
return "foo"; 
} else { 
return "bar"; 
} 
} 
O comportamento quando i==0 não foi testado
Mockista Míope 
@Test 
public void 
shouldPerformActionGivenTrue() { 
foo(mockCollab, true); 
verify(mockCollab).doAction(); 
} 
@Test 
public void 
shouldNotPerformActionGivenFalse() { 
foo(mockCollab, false); 
verify(never(),mockCollab).doAction(); 
} 
public static String foo(Collaborator c, 
boolean b) { 
if ( b ) { 
return c.doAction(); 
} 
return "FOO"; 
} 
Retorno da função nunca foi testado
Operadores de mutação 
● Exclusão de declarações 
● Duplicação ou inserção de declarações 
● Negação de subexpressões booleanas 
● Substituições: 
○ Operadores aritiméticos (+, -, *, /) 
○ Relações booleanas (==, !=, <, <=, >, >=) 
○ Variáveis do mesmo escopo (tipos devem ser compatíveis) 
Escore de mutação = № de mutantes mortos / № total de 
mutantes
Por que? 
● Ajuda a criar suítes de teste efetivas 
● Propósito educacional 
● Mostra quanto pode-se confiar numa suite de teste 
○ Código legado 
● Ajuda na refatoração e na criação de testes de 
caracterização 
● Verificar se alguma implementação está bem testada
O que não resolve? 
● Caro para gerar e executar mutantes 
● Limitado aos operadores de mutação 
● Útil para teste unitários (doing things right) 
● Ainda devem existir testes funcionais (doing the right 
things)
Ferramentas 
● PIT for Java 
● Mutant for Ruby 
● PyMuTester for Python
PIT num projeto 
real
Fontes 
● http://pitest.org/ 
● http://solnic.eu/2013/01/23/mutation-testing-with-mutant. 
html 
● http://en.wikipedia.org/wiki/Mutation_testing 
● https://github.com/mbj/mutant 
● http://www.parasoft.com/products/article.jsp? 
articleId=291 
● http://www.techopedia.com/definition/20905/mutation-testing
Perguntas? 
Luís Armando Bianchin 
labianchin@thoughtworks.com

Teste de Mutação

  • 1.
    Teste de mutação Luís Armando Bianchin Consultant Developer
  • 2.
    Agenda ● Problema ● O que é teste de mutação? ● Exemplos ● Por que? ● Ferramentas ● Uso num projeto real
  • 3.
    Problema ● Ostestes estão corretos? ● Cobrem todos requisitos? ● Qual a qualidade dos testes?
  • 4.
    Problema ● Coberturade linhas apenas verifica execução de código ● 100% de cobertura != boa suite de testes ● Apenas testes "happy path" ou fáceis ● Código apenas parcialmente testado
  • 5.
    Os testes são capazes de detectar falhas?
  • 6.
    Origem ● Propostona Academia ~ 1978 ● Yale University e Georgia Institute of technology ● Hipótese do programador competente ○ Programas quase perfeitos ○ Falhas pequenas ○ Pequenas alterações para correção
  • 7.
    O que éteste de mutação? ● Introduz falhas (mutações) na implementação ○ Alterações semânticas ● Roda os testes ● Os testes realmente quebraram? ● Mutações mortas ou vivas? ● Os testes identificaram as falhas?
  • 8.
    Exemplo Mutação detroca de && para || if (a && b) { c = 1; } else { c = 0; } if (a || b) { c = 1; } else { c = 0; }
  • 9.
    Efeito colateral nãotestado @Test public void shouldFailWhenGivenFalse() { assertEquals("FAIL", foo(false)); } @Test public void shouldBeOkWhenGivenTrue() { assertEquals("OK", foo(true)); } public static String foo(boolean b) { if ( someThing(i) ) { doImportantBusinessLogic(); return "OK"; } return "FAIL"; } Não verifica se doImportantBusinessLogic foi chamado
  • 10.
    Teste de limiteincompleto @Test public void shouldReturnBarWhenGiven1() { assertEquals("bar", foo(1)); } @Test public void shouldReturnFooWhenGivenMinus1() { assertEquals("foo", foo(-1)); } public static String foo(int i) { if ( i >= 0 ) { return "foo"; } else { return "bar"; } } O comportamento quando i==0 não foi testado
  • 11.
    Mockista Míope @Test public void shouldPerformActionGivenTrue() { foo(mockCollab, true); verify(mockCollab).doAction(); } @Test public void shouldNotPerformActionGivenFalse() { foo(mockCollab, false); verify(never(),mockCollab).doAction(); } public static String foo(Collaborator c, boolean b) { if ( b ) { return c.doAction(); } return "FOO"; } Retorno da função nunca foi testado
  • 12.
    Operadores de mutação ● Exclusão de declarações ● Duplicação ou inserção de declarações ● Negação de subexpressões booleanas ● Substituições: ○ Operadores aritiméticos (+, -, *, /) ○ Relações booleanas (==, !=, <, <=, >, >=) ○ Variáveis do mesmo escopo (tipos devem ser compatíveis) Escore de mutação = № de mutantes mortos / № total de mutantes
  • 13.
    Por que? ●Ajuda a criar suítes de teste efetivas ● Propósito educacional ● Mostra quanto pode-se confiar numa suite de teste ○ Código legado ● Ajuda na refatoração e na criação de testes de caracterização ● Verificar se alguma implementação está bem testada
  • 14.
    O que nãoresolve? ● Caro para gerar e executar mutantes ● Limitado aos operadores de mutação ● Útil para teste unitários (doing things right) ● Ainda devem existir testes funcionais (doing the right things)
  • 15.
    Ferramentas ● PITfor Java ● Mutant for Ruby ● PyMuTester for Python
  • 16.
  • 17.
    Fontes ● http://pitest.org/ ● http://solnic.eu/2013/01/23/mutation-testing-with-mutant. html ● http://en.wikipedia.org/wiki/Mutation_testing ● https://github.com/mbj/mutant ● http://www.parasoft.com/products/article.jsp? articleId=291 ● http://www.techopedia.com/definition/20905/mutation-testing
  • 18.
    Perguntas? Luís ArmandoBianchin labianchin@thoughtworks.com