Um pouco sobre cobertura de código e cobertura de testes
--
É muito comum tentarmos quantificar atividades, recursos, defeitos, o código escrito e também os testes desenvolvidos. Nesse aspecto de quantificação podemos incluir dois temas próximos e facilmente confundidos, são eles:
- cobertura de código (code coverage);
- cobertura de testes (test coverage).
Essas duas características podem ser consideradas como métricas de um projeto de software.
O que é a cobertura de código? 🤔
Falando inicialmente sobre a cobertura de código, o seu principal objetivo é encontrar códigos não testados. Martin Fowler em um dos seus artigos sobre testes e métricas, discute sobre Test Coverage e Code Coverage, ilustrando da seguinte forma:
É interessante destacar que a qualidade do software não pode ser quantificada por essa métrica. A cobertura de código irá nos ajudar na avaliação da suíte de testes de testes que foi escrita para o código existente.
Um sistema com alta cobertura de código significa que foi mais exaustivamente testado e tem uma menor chance de conter erros, ao contrário de um sistema com baixa cobertura de código.
Como a cobertura de código pode ajudar? 🤗
A cobertura de código irá exercitar o código desenvolvido, permitindo explorar:
- Caminhos felizes; 😀
- Caminhos infelizes; 😢
- Caminhos alternativos; 🤨
Irá ajudar a encontrar código inútil/supérfluo/mal escrito, permitindo descobrirmos códigos que não são testados ou códigos inalcançados.
Facilita o aumento da cobertura de testes, uma vez que podemos descobrir cenários que não estão sendo explorados.
E possibilita encontrar gaps nos requisitos, nos casos de testes e defeitos a níveis de unidade, prevenindo assim defeitos em estágios iniciais do ciclo de vida do projeto.
Cobertura de código x cobertura de testes 🧐
A cobertura de código não é a mesma coisa que cobertura de testes.
A cobertura de código, sendo uma métrica quantitativa, visa medir quanto (%) do software é coberto/exercitado ao executar um determinado conjunto de casos de testes.
Enquanto que a cobertura de testes, sendo uma métrica qualitativa, visa medir a eficácia dos testes perante os requisitos testados, determinando se os casos de testes existentes cobrem os requisitos que estão sendo testados.
Tipos básicos de cobertura de código 📖
A cobertura de código possui alguns tipos básicos, tais como:
- Function — verifica quantas funções do código são chamadas;
- Statement — verifica quantas instruções do código são executadas;
- Branch — verifica se cada ramificação de cada estrutura de controle (incluindo if/else, switch case, for, while) é executada;
- Condition — verifica se cada sub-expressão booleana são avaliadas ambas como verdadeiras e falsas;
Cobertura de código é a bala de prata? ⁌
Não.
Apesar de existirem valores considerados como padrão esperado pelo mercado, não há garantia que o código será livre de defeito por termos uma cobertura de código alta.
A cobertura do código é objetiva, mas não nos diz o quão bem testado um software realmente é, enquanto a cobertura do teste é subjetiva e dá um pouco mais de informação.
Dinâmica — Subjetividade e utilidade
A seguir apresento um resumo do artigo de Dan Ashby onde ele comenta sobre a confusão entre os conceitos de cobertura de código e cobertura de testes. Ele explica o que seria a cobertura de código e a cobertura de testes a partir de uma comparação com um brinquedo do seu filho, Angus.
O brinquedo em questão é um carro educativo com buracos e peças em formas geométricas de encaixar.
Iniciando a analogia, o bloco vermelho em destaque, representa os dados que um usuário pode inserir/passar/exercitar em um recurso específico.
Empurrar o bloco pelo buraco cobriria essencialmente esse código. Essa ação poderia ser visto como 100% de cobertura do código. Nós empurramos o bloco pelo buraco, portanto exercitamos 100% do código desse recurso.
Porém… e se tivessem 16 maneiras diferentes de inserir o bloco?
Olhando mais de perto para o bloco, veremos que existem 16 maneiras diferentes de passar esse bloco pela mesmo buraco.
- Face superior x 4 lados;
- Face inferior x 4 lados;
- Podendo ser empurrado de dentro para fora como de fora para dentro, logo temos 2 maneiras;
Total: (4 + 4) x 2 = 16 possibilidades.
Daí, vemos que o único teste inicial potencialmente nos deu 100% de cobertura de código. Mas que na verdade ele representava apenas uma cobertura de teste de 6,25%.
Se analisarmos mais um pouco…
Há inevitavelmente mais testes nos quais ainda não pensamos…Outros buracos com outras formas.
E algumas dessas outras formas também se encaixam no buraco retangular anterior.
De vários lados também …
O bloco em forma de cubo possibilita 48 maneiras de passar através do buraco retangular.
Sendo assim…
Métricas de porcentagem de cobertura são extremamente subjetivas e se relacionam bastante no tempo, com base nas informações claramente conhecidas.
Nem sempre conseguem dizer algo sobre a qualidade do seu software ou a qualidade dos seus testes.
E aí, você transportaria sua carga no caminhão acima?
Referências:
https://www.atlassian.com/continuous-delivery/software-testing/code-coverage
https://en.wikipedia.org/wiki/Code_coverage
https://www.martinfowler.com/bliki/TestCoverage.html
https://github.com/coreinfrastructure/best-practices-badge/blob/master/doc/test-coverage-criteria.md
https://test.io/blog/code-coverage-vs-test-coverage/
https://danashby.co.uk/2019/02/14/code-coverage-vs-test-coverage/
https://www.sealights.io/test-metrics/code-coverage-vs-test-coverage-pros-and-cons/
https://medium.com/@oieduardorabelo/cobertura-de-código-explicada-ba1516db7dbd