A crescente adoção de testes automatizados como uma prática corriqueira dentro das equipes de desenvolvimento trouxe com ela a métrica chamada de code coverage, que indica o quanto (%) seu código de produção está coberto por testes.
Em seguida, as diversas ferramentas que possibilitaram automatizar as práticas de CI/CD também permitiram adicionar à pipeline de build/deploy um passo para o cálculo do code coverage e a publicação do resultado da análise em ferramentas como o SonarQube e o Coveralls.io.
Com isso, ganhamos agilidade (análise de code coverage executada automaticamente a cada build) e visibilidade (resultado publicado num formato organizado, exibindo o % de cobertura em nível de pacote, classe e método).
Como a “cereja do bolo”, ainda conseguimos barrar a pipeline em determinada etapa, caso o percentual de coverage esteja abaixo de um limite considerado aceitável.
Soa muito bem, não? Agora, o quão isso tudo está perto de garantir qualidade do software? E o que acontece quando a equipe programa cegamente para atingir o limite mínimo estipulado na pipeline?
CODE COVERAGE E QUALIDADE
Um percentual de, digamos, 90% de code coverage é um belo número. O ponto é que este número só significa que, bem, você tem 90% de código coberto por testes. Isoladamente, este número não indica o quão BEM testado está o código.
Um olhar atento em uma suíte de testes e é bem provável que encontremos testes cujas asserções não garantem muita coisa, como:
- testes de API que checam o status code do response HTTP, mas desprezam o body;
- testes que apenas verificam que o retorno do método da SUT é diferente de nulo ou uma lista não vazia;
Testes assim somente satisfazem a meta de coverage, mas não irão ajudar muito quando um bug for introduzido no código.
Outro fator que o code coverage não ajuda é quanto à manutenibilidade do código de teste. Não é raro encontrarmos suítes de testes de baixa qualidade, apresentando poucas ou nenhuma destas características fundamentais.
Desta forma, a suíte de testes, com seus belos 90% de code coverage, acaba sendo um fardo grande para a equipe, prejudicando a produtividade e, consequentemente, gerando altos custos de manutenção.
Por fim, o percentual de coverage ignora a estratégia de testes adotada. Em outras palavras, você pode chegar a 100% de cobertura escrevendo 1000 testes end-to-end e nenhum teste de unidade, o que, além de menos assertivo quanto à localização do problema quando um teste falha, é muito mais custoso em termos de desenvolvimento e execução da suíte.
OBSESSÃO PELO NÚMERO
Quando a equipe trabalha cegamente para atingir o limite esperado (ou imposto?) de coverage, principalmente quando ele é uma barreira para seguir na pipeline de deploy, ela negligencia todos os pontos mencionados anteriormente.
Sendo assim, a equipe acaba não evoluindo tecnicamente, no que se refere a boas práticas de testes, já que, provavelmente, sequer entende os benefícios dos mesmos.
CONCLUINDO
Use a métrica de code coverage, na melhor das hipóteses, como um indicador de que as coisas estão indo mal e não de que estão indo bem. Isto é, use o percentual muito baixo como um grande alerta de que o código está sendo pouco testado e identifique a causa raiz. Não existe um número mágico para indicar um “percentual muito baixo”. Apenas atente-se a quedas do tipo “de 70% para 50%” e investigue.
Não fique cegamente correndo atrás de um número. Preocupe-se mais com a qualidade dos testes que estão sendo escritos: se eles cobrem os cenários principais, se suas asserções realmente testam o que deviam testar, se não há mais de 1 teste validando a mesma coisa, se eles são fáceis de manter, etc. Aqui mesmo no blog, há uma porção de artigos sobre o assunto.
E você? Tem usado essa métrica no dia-a-dia? De que forma? Comente-aí!
Até o próximo!
Recentemente adicionamos essa regra no nosso pipeline e me identifiquei bastante quando você diz “um indicador de que as coisas estão indo mal”.
Acredito que para esses tipos de coisa não conheço nada que supere um bom code review. Mas ter algo automatizado que alerte a equipe pode ser interessante no dia a dia.
CurtirCurtir
Sem dúvidas, pairing e code review são ótimos pra qualidade do software. A métrica é aquilo: alerta se tá muito mal e só.
Abs, camarada!
CurtirCurtir
Ótimo post, Robson! Compartilho de sua visão, principalmente no que diz respeito à baixa cobertura de código sendo sinal de que as coisas vão mal, porém a alta cobertura não necessariamente significando que está tudo ótimo. Acho que esta é a nuance que muita gente não entende: enquanto a cobertura de código não deve te dar a ilusão de segurança, ela também não é inútil quando se entende sua limitação.
Porém, gostaria de saber sua opinião sua testes de mutação. Acredito que o uso dessa técnica pode melhorar e muito a confiabilidade nos testes. E aí neste caso, a relevância da cobertura
aumenta bastante. Aqui está um post que escrevi há algum tempo sobre o tema: https://carlosschults.net/pt/testes-de-mutacao/
Abraço!
CurtirCurtir
Oi, Carlos, blz?
Pelo que já li, acredito que esses testes devam ajudar a pegar testes mal escritos e test cases faltando, mas ainda não avaliei nenhuma ferramenta desse tipo para poder falar com mais propriedade. Se cumprem bem o papel citado, são algo mais palpavel do que o code coverage.
Obrigado por comentar.
[]s
CurtirCurtir
Para o .NET, eu recomendo o Stryker.NET. É um port do Stryker Mutator, que foi feito originalmente para o JavaScript. É uma ferramenta ainda no início, mas já é funcional:
https://github.com/stryker-mutator/stryker-net
CurtirCurtir
Boa. Foi o primeiro que encontrei mesmo. Vou dar uma olhada. Vlw!
CurtirCurtir
Perfeito Robson. Um baixo coverage é um alerta de que a confiabilidade do software é baixa, mas um alto coverage também não significa que o software está imune a falhas. Gosto de pensar que o code coverage funciona como uma busula, que nos ajuda a chegar em metricas melhores, nem de longe pode ser levada em consideração isoladamente.
Parabéns pelo post
CurtirCurtir
Com certeza. Já vi inúmeros códigos com cobertura boa, mas os testes eram ruins, sem testar grande coisa.
[]s
CurtirCurtido por 1 pessoa