Teste de Mutação
Click here to load reader
-
Upload
luis-bianchin -
Category
Technology
-
view
434 -
download
1
description
Transcript of Teste de Mutação
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
● 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?
O que é teste de mutação?
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
@Testpublic void shouldReturnBarWhenGiven1() { assertEquals("bar", foo(1));}
@Testpublic 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
@Testpublic void shouldPerformActionGivenTrue() { foo(mockCollab, true); verify(mockCollab).doAction();}
@Testpublic 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