Medindo a complexidade do seu código JavaScript

Já mostramos aqui no Tableless ferramentas para testes e ferramentas para garantir o padrão do seu código JavaScript, mas, enquanto esses utilitários asseguram uma consistência maior, eles nem sempre acabam com complexidades desnecessárias. Neste artigo vamos falar sobre complexidade ciclomática e mostrar uma ferramenta para análise de códigos JavaScript, a biblioteca Plato. Complexidade Ciclomática A

Já mostramos aqui no Tableless ferramentas para testes e ferramentas para garantir o padrão do seu código JavaScript, mas, enquanto esses utilitários asseguram uma consistência maior, eles nem sempre acabam com complexidades desnecessárias.

Neste artigo vamos falar sobre complexidade ciclomática e mostrar uma ferramenta para análise de códigos JavaScript, a biblioteca Plato.

Complexidade Ciclomática

A primeira regra de funções é que elas devem ser pequenas. A segunda regra de funções é que elas devem ser ainda menores.
— Uncle Bob

Funções devem fazer uma coisa apenas. Fazê-la bem. Fazer somente ela.
— Uncle Bob

Explicando de forma bem direta, complexidade ciclomática é uma métrica do número de caminhos possíveis no seu código. Por exemplo, vejamos o código abaixo:

A função authenticate possui valor 2 de complexidade ciclomática. Na prática, isso quer dizer que precisaríamos escrever dois testes unitários para cobrir todos os possíveis caminhos. Ou seja, quanto mais caminhos, maior a complexidade ciclomática e, quanto maior a complexidade ciclomática, mais difícil será de manter/testar seu código.

Estudos recomendam 10 como o valor máximo que você deve permitir de complexidade ciclomática no seu método ou sua função. Este é um bom valor, mas tenha em mente que 10 já é uma complexidade alta e não deve, de forma alguma, ser a média de complexidade do seu projeto.

Bad Fix

Outra métrica tirada a partir da complexidade ciclomática é a probabilidade de uma correção injetar novos bugs no seu código. O pessoal da Aivosto, uma empresa especializada em ferramentas para desenvolvedores, chegou a seguinte tabela:


  Probabilidade de “bad fix”


  5%


  20%


  40%


  60%

Segundo a pesquisa da Aivosto, uma correção aplicada em um método com complexidade ciclomática 25 tem 20% de chances de introduzir um novo bug na sua aplicação. Tente lembrar quantas vezes isso já aconteceu com você? E tente lembrar também do tamanho do método ou função que você estava “corrigindo”. Por isso é muito importante tentar medir tudo a respeito do seu código.

Plato

Desenvolvida por Jarrod Overson, a ferramenta Plato aplica na prática todas as teorias de medição de complexidade ciclomática, exibindo na forma de gráficos dados como taxa de mantenabilidade, bugs estimados e erros de lint.

A instalação é feita através do npm, gerenciador de pacotes do nodejs:

A forma mais básica de uso é a seguinte:

Onde -d report é a flag para indicar o diretório report como saída do seu relatório e src é o diretório dos arquivos JavaScript a serem analisados.

Outras opções importantes são as flag -r para ler o diretório recursivamente e -x para excluir arquivos baseados em uma regex.

Os relatórios do Plato armazenam históricos e é bem interessante ver os números subindo e descendo durante o desenvolvimento do seu projeto. Uma prática legal é guardar e exibir o relatório em algum lugar disponível para todo o seu time.

Exemplos de relatórios

Abaixo temos alguns exemplos de relatórios disponibilizados no repositório do projeto, gerados a partir de bibliotecas e utilitários populares:

  • jquery
  • grunt
  • marionettejs

Bugs estimados

Um gráfico que chama a atenção nos relatórios do Plato é o de bugs estimados. Afinal de contas, entregar um produto sem bugs é (ou deveria ser) o objetivo final de qualquer desenvolvedor.

Maurice Howard Halstead criou um conjunto de fórmulas para medir coisas como volume, esforço, dificuldade e bugs estimados em um código. As fórmulas são baseadas nos números únicos e totais de operadores e operandos.

Não vou entrar muito em detalhes sobre os valores e as fórmulas, mas é bem interessante ler sobre esse assunto (não precisa ser o livro, a Wikipedia mesmo fornece uma página bem completa sobre as fórmulas).

Overson também desenvolveu um módulo que disponibiliza uma task Grunt para relatórios Plato.

A instalação segue o padrão de pacotes Grunt:

Uma vez instalado o pacote, basta carregar a task no seu Gruntfile.js e rodar a task com o comando grunt plato:

Métricas, métricas e mais métricas

Medir o código do seu projeto ajuda você e seu time a entender e prevenir problemas. Com a ajuda de métricas você vai conseguir manter um código fácil de ler e entender. Além de métricas dos níveis de complexidade também é importante possuir um relatório visível de cobertura de testes e uma documentação simples e direta do seu projeto.

Apesar do nome pomposo e de muita teoria, não é pra ninguém ficar assustado. Pode parecer um conceito avançado, mas na verdade é uma coisa muito básica: o que você estará fazendo é medir se é fácil (ou difícil) manter o seu código.

E lembrem-se: nunca refatore um código sem que ele possua uma cobertura de testes satisfatória!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *