Métricas de Qualidade de Código: Cobertura, Complexidade Ciclomática
Introdução
O desenvolvimento de software é um processo contínuo que envolve a criação, manutenção e melhoria das aplicações software. À medida que as aplicações crescem em complexidade e escala, é cada vez mais importante medir e melhorar a qualidade do código-fonte.
Uma abordagem comum para alcançar isso é utilizar métricas de qualidade de código, que permitem avaliar aspectos específicos do código e identificar áreas de melhoria. Nesse artigo, vamos focar nas duas métricas mais importantes: Cobertura e Complexidade Ciclomática.
Essas métricas são relevantes porque ajudam a garantir que o código esteja bem estruturado, fácil de manter e menos propenso a erros. Elas também permitem avaliar se as melhorias implementadas tiveram um impacto positivo na qualidade do código.
Ao final desse artigo, você terá uma compreensão clara sobre o que são Cobertura e Complexidade Ciclomática, como elas são medidas e por quais razões são importantes no desenvolvimento de software.
O que é e por que importa
A Cobertura é a medida quantitativa da percentagem de linhas de código dentro de um determinado conjunto de teste que são executadas durante a execução dos testes. Ela é calculada dividindo o número de linhas cobertas pelos testes pelo total de linhas de código do software e multiplicando por 100.
Por exemplo, se um conjunto de teste abrange 80% das linhas de código de um projeto e há 10 mil linhas em todo o código, a cobertura é de 80%.
A Cobertura é importante porque demonstra que os testes estão cobrindo as áreas mais críticas do software. Com uma boa cobertura, podemos ter confiança na qualidade do produto e reduzir o risco de erros ocultos.
Por outro lado, a Complexidade Ciclomática (CC) é uma métrica que mede a complexidade de um módulo de código considerando não apenas a estrutura, mas também as interações entre as instruções. Ela está relacionada ao número de decisões tomadas pelo programa ao executar, e seu valor aumenta à medida que o programa torna-se mais complicado.
A Complexidade Ciclomática é calculada usando a fórmula: CC = P + 1, onde P é o número de predicados (condições) no código. Por exemplo, se um bloco de código tem quatro condições e uma instrução sem condição, a complexidade ciclomática seria de 5.
A Complexidade Ciclomática é importante porque ajuda a identificar áreas do código que são propensas a erros ou necessitam de revisão. Ela também é útil para avaliar se as melhorias implementadas na codificação resultaram em uma redução da complexidade, tornando o software mais fácil de manter e menos propenso a problemas futuros.
Como funciona na prática
Para entender como a Cobertura e a Complexidade Ciclomática funcionam na prática, vamos analisar as etapas abaixo:
Calculando a Cobertura
- Especificar testes: Identifique os cenários de teste que precisam ser cobertos. Isso inclui casos de sucesso e erro para garantir que o software seja testado em todas as possibilidades.
- Mapeamento do código: Analise o mapa do código, identificando as linhas de código importantes para garantir a execução dos cenários de teste planejados.
- Implementação de testes: Implemente os testes correspondentes às especificações. Certifique-se de que cada linha crítica esteja sendo coberta por um ou mais testes.
Calculando a Complexidade Ciclomática
- Análise do código: Analise as estruturas condicionais (if, switch, etc.) e os loops no código para determinar o número de predicados (P) presentes.
- Contagem de decisões: Para cada bloco de código, contabilize o número de decisões tomadas. Isso inclui não apenas as estruturas condicionais, mas também o loop.
- Cálculo da Complexidade Ciclomática: Use a fórmula CC = P + 1 para calcular a Complexidade Ciclomática do módulo de código.
Integração com Ferramentas
- Configuração das ferramentas: Configure as ferramentas de teste e análise de código para coletar dados sobre a Cobertura e a Complexidade Ciclomática.
- Execução dos testes: Execute os cenários de teste planejados para calcular a Cobertura.
- Análise da complexidade ciclomática: Use ferramentas que podem calcular a Complexidade Ciclomática diretamente, sem necessidade de uma análise manual.
Essas etapas fornecem uma visão geral de como implementar e integrar as métricas de Qualidade de Código no seu processo de desenvolvimento.
Exemplo real
Teste de Funcionalidade - Autenticação Usuário
public class UsuarioController {
public boolean autenticarUsuario(String login, String senha) {
// Buscar no banco de dados a senha correspondente ao login
String senhaBd = buscarSenhaNoBanco(login);
if (senhaBd != null && senhaBd.equals(senha)) {
return true;
} else {
return false;
}
}
private String buscarSenhaNoBanco(String login) {
// Simulando busca no banco de dados
String senha = "password123";
if (login.equals("admin")) {
senha = "senhaAdmin";
}
return senha;
}
}
Neste exemplo, temos um método autenticarUsuario que verifica se o login e a senha fornecidas são válidos. O método buscarSenhaNoBanco é usado para simular a busca da senha no banco de dados.
Considerando as métricas de Qualidade de Código, podemos calcular a Cobertura do código como segue:
- Linha 1:
public boolean autenticarUsuario(String login, String senha): Essa linha é importante porque define o método que será testado. - Linhas 3 e 4:
String senhaBd = buscarSenhaNoBanco(login);eif (senhaBd != null && senhaBd.equals(senha)): Essas linhas são importantes porque definem a lógica da autenticação. - Linha 9:
return false;: Essa linha é importante porque define o comportamento caso a senha seja inválida.
Portanto, se implementarmos os testes correspondentes às especificações, teremos cobertura para as linhas de código importantes.
Agora, vamos calcular a Complexidade Ciclomática do método autenticarUsuario:
- Estruturas condicionais: 1 (na linha 4)
- Loops: 0
- Número de decisões: 2
Usando a fórmula CC = P + 1, calculamos:
CC = 2 + 1 = 3
Portanto, a Complexidade Ciclomática do método autenticarUsuario é 3.
Essa análise pode ser feita para outros métodos da classe UsuarioController, garantindo que o software seja testado em todas as possibilidades e que a complexidade ciclomática seja minimizada.
Boas práticas e armadilhas comuns
Boas práticas
- Use testes unitários para cobrir todas as possibilidades de cada método, garantindo que a lógica esteja correta.
- Implemente métodos pequenos e focados em uma tarefa específica, facilitando o manuseio da complexidade ciclomática.
- Utilize variáveis com nomes descritivos para melhorar a legibilidade do código.
Armadilhas comuns
- Testes insuficientes: é fundamental implementar testes que cubram todas as possibilidades de cada método, evitando assim falhas ocultas.
- Complexidade ciclomática alta: métodos com muitas decisões podem tornar difícil a manutenção do código. Tente dividir esses métodos em menores e mais focados.
Conclusão
Em resumo, as métricas de qualidade de código são ferramentas fundamentais para avaliar a eficácia e manutenibilidade do software. A Cobertura de Código garante que os testes estejam abrangendo todas as linhas críticas do código, enquanto a Complexidade Ciclomática identifica áreas onde o código pode ser otimizado.
Para seguir em frente, é importante implementar testes unitários para cada método e garantir que eles estejam cobrindo todas as possibilidades. Além disso, é recomendável dividir métodos com muitas decisões em menores e mais focados para minimizar a complexidade ciclomática.
Aprofundamento em áreas relacionadas, como Test-Driven Development (TDD) e refatoração de código, pode ajudar a melhorar ainda mais a qualidade do software. Além disso, é importante monitorar as métricas e ajustá-las periodicamente para garantir que o software esteja evoluindo de acordo com os requisitos da empresa.
Referências
- Fowler, M. (2022). Code Smells. Disponível em: https://www.martinfowler.com/bliki/CodeSmell.html. Acesso: 2024.
- OWASP (Organização para a Segurança no Desenvolvimento de Aplicativos Web). (2023). Princípios de Design de Software. Disponível em: https://owasp.org/www-pdf-archive/OWASP%20Design%20Principles.pdf. Acesso: 2024.
- Kent Beck. (2009) “Test Driven Development By Example” pág.12. Capítulo "The Story of the Three Little Pigs"
- Thoughtworks.com. (2023). A Guide to Code Quality Metrics and Tools. Disponível em: https://www.thoughtworks.com/insights/blog/code-quality-metrics-tools. Acesso: 2024.
- Martin Fowler. (2018) “Refactoring – Improving the Design of Existing Code” Capítulo "Don’t Repeat Yourself".