Contribuir para o aumento do nível de confiança, prevenir e encontrar defeitos estão entre os principais objetivos que queremos alcançar quando testamos um software. Porém, para atingirmos essas metas não existe uma simples receita de bolo e precisamos estar sempre atentos para maximizar as nossas chances de entregarmos constantemente software de qualidade e que atenda às necessidades dos clientes.
Apesar de nossos esforços, invariavelmente temos que lidar com os defeitos escapados, que normalmente implicam em stress, re-trabalho e desgaste na relação com o cliente. Em meio ao problema, uma das primeiras ações que temos é a análise da causa raiz, ou seja, identificar o porquê do defeito ter ocorrido e consequentemente do mesmo não ter sido identificado nas etapas anteriores de validação.
Diversos podem ser os motivos para a falha na detecção do defeito, por exemplo:
– Cenário de teste não estava coberto.
– Teste existia, mas não foi priorizado para o ciclo de execução.
– Teste existia, foi priorizado, porém não foi executado corretamente.
– Teste existia, foi priorizado, executado corretamente, porém diferenças de ambiente não permitiram a detecção da falha.
– Etc.
Porém, ainda há um outro motivo, que talvez seja um dos mais frustrantes – O teste existe, mas está errado.
Quando isso acontece, independente de planejarmos corretamente, o teste, seja ele manual ou automático, nunca nos trará o resultado correto e a falha inevitavelmente aparecerá em produção. Nesses casos, ainda temos como dificuldade adicional o fato de que a re-execução do nosso teste não ajudará na reprodução do erro, podendo inclusive gerar ruído na comunicação e dificuldades na identificação da causa do problema e consequentemente em sua correção.
Identificar testes com defeito não é algo simples e corremos o risco de executá-lo diversas vezes e confiarmos em resultados enganosos. Para tentar minimizar esse tipo de situação, podemos realizar algumas ações:
– Revisar os testes existentes
– Se forem testes manuais, mudar o responsável pela execução
– Aprofundar-se no funcionamento de mocks e stubs utilizados para teste
– Conhecer as limitações das ferramentas utilizadas
– Revisar as pré-condições e o ambiente de validação
E você já enfrentou o problema de ter falhas escapadas devido a testes defeituosos? Que ações tomou para tentar evitar que o problema se repetisse?
A análise de mutantes é uma estratégia presente na literatura para a avaliação de conjuntos de casos de teste. Nela, operadores de mutação são definidos e estes geram versões “mutantes” do sistema a ser testado.
Com um determinado conjunto de casos de teste passando, ou seja, aprovando um certo sistema, a ideia é ter um conjunto de casos de teste que, além de passar para a versão não “mutada”, falhar quando executar sobre um mutante, matando-o.
É bem viável a inserção da análise de mutantes no contexto do desenvolvimento de sistemas. Poderia ser realizada após uma iteração de teste de integração, coletando métricas de “mutantes mortos”, com o objetivo de ter muitas mutações (o máximo possível) e o máximo de mutantes mortos!
Olá João,
Excelente contribuição.
Obrigado
A ideia dos testes mutantes é muito boa, mas acredito que exige um bom tempo para fazer essa analise, teria que ser acordado a criacao dos mutantes no cronograma dos testes.
Mas é bem legal a ideia.
Olá João!
Gosto da técnica de “Injeção de Falhas” não mencionada no artigo.
É algo simples que também resolve o problema em questão.
Trata-se de um acordo prévio onde o programador insere um determinado número de erros conhecidos apenas por ele na aplicação.
A suite de teste deve ser capaz de detectar no mínimo os erros inseridos propositalmente pelo programador.
Caso os erros não sejam detectados, está evidente que a análise precisa ser revista.
Abraços,
Eduardo Souza
Parece com o princípio dos mutantes, com a diferença que o operador de mutação é o próprio programador! Esses operadores são algo como:
– ir em um comando condicional e trocar ‘>’ por ‘<='
– num comando iterativo, trocar 'i++' por 'i–'
– algo mais elaborado ou relacionado com o domínio da aplicação
A abordagem manual é mais pontual em alguma desconfiança, mas não consegue escalar bem, ou seja, gerar muitas variações e ver o que acontece. Já uma análise de mutantes, como manda o figurino, pode ser feita automaticamente, e depois apenas coletar os resultados, gerando milhares de versões mutantes do SUT (system under test).
Com o resultado, dá pra saber quais testes são mais problemáticos (os que não matam mutantes ou matam poucos) e quais são os que matam mais mutantes!
Parece mesmo!
A análise de mutantes é uma excelente técnica para testes unitários, onde a variação dos operadores lógicos é apenas uma das dezenas de mutações possíveis, mas explora as características das unidades separadamente.
A implementação é muito parecida. A diferença é que na injeção de falhas o programador não se preocupa com todas as variações necessárias. Até por que todas as variações necessárias inviabilizaria o andamento dos testes. São casos bem específicos.
Acredito de ambas sejam eficazes, porém cada uma no seu contexto.
[…] O que fazer quando o defeito está no teste ? […]