Cyclomatic Complexity: o número que diz quantos testes sua função realmente precisa

Tech Leads e Staff Engineers que escrevem testes raramente têm um critério objetivo para decidir quantos testes uma função precisa. Há um — e ele tem cinquenta anos de idade.

Cyclomatic Complexity conta quantos caminhos lineares independentes há no fluxo de uma função. Esse número é exatamente o de casos de teste necessários para cobrir todos os caminhos. Foi criado por Thomas McCabe em 1976 e ainda é o instrumento mais direto para medir testabilidade.

TL;DR

Cyclomatic Complexity conta quantos caminhos lineares independentes existem no fluxo de uma função. Esse número é exatamente o de casos de teste necessários para cobrir todos os caminhos. Foi criado por Thomas McCabe em 1976 e ainda é o instrumento mais direto para medir testabilidade.

Para quem  Tech Leads · Staff Engineers Leitura  ~5 min Funil  Awareness

O que este artigo explora:

  • O problema de não ter critério objetivo para definir cobertura de testes
  • Como a métrica é calculada — passo a passo, com exemplo de código
  • Como interpretar o número na prática e quais thresholds operacionais usar
  • O que a Ciclomática não captura (e onde a Cognitive Complexity entra)
  • Os três sintomas que aparecem quando a Ciclomática passa de 10
  • A cura via modularização — e por que comentários não resolvem
  • Plano operacional em 4 passos para começar hoje
  • Ferramentas que medem a Ciclomática out-of-the-box
  • Cinco pontos-chave para levar embora
§ 1 O Problema

O problema

Você abre um PR. O reviewer comenta: "falta cobertura de teste aqui". Você responde: "escrevi 3 testes, cobre o happy path e dois edge cases". Ele diz: "acho que falta um caso". Você acha que não.

Quem está certo?

Sem critério objetivo, vira opinião. Os dois saem da revisão com sensação ruim. A função sobe pra produção. Três meses depois, um caso não testado vira um incidente.

A Cyclomatic Complexity elimina essa discussão. Ela conta o número de caminhos lineares independentes que o fluxo de execução pode tomar. Esse número é a quantidade mínima de testes para cobrir todos os caminhos. Não é estimativa. É matemática.

Como a métrica é calculada

Thomas McCabe propôs a fórmula em 1976. O cálculo é determinístico — cada construção que desvia o fluxo linear adiciona +1:

  • Cada if / else if → +1
  • Cada case em um switch → +1
  • Cada for, while, do-while → +1
  • Cada &&, || em condicionais → +1
  • Cada catch em um try-catch → +1

Uma função sem nenhum desvio (apenas instruções sequenciais e um return) tem complexidade 1. Cada bifurcação adiciona um caminho. O total é o número de testes necessários para cobrir todos os caminhos.

JavaScript Cyclomatic Complexity = 4
// Cyclomatic Complexity = 4
function classifyOrder(order) {
  if (order.value > 1000) return 'PREMIUM';      // +1
  if (order.value > 100) return 'STANDARD';      // +1
  if (order.items.length > 10) return 'BULK';    // +1
  return 'BASIC';                                // path base = 1
}
// 4 caminhos = mínimo 4 testes para cobertura total

Como interpretar o número na prática

A fórmula resumida é: 1 (caminho base) + Σ ramificações. Some todas as construções que desviam o fluxo e adicione 1. O resultado é a sua Ciclomática — e a quantidade mínima de testes para cobertura total de caminhos.

Para uso operacional em revisão de código, três faixas funcionam bem como referência:

  • Faixa saudável (≤ 10): o método é testável e revisável sem fricção.
  • Zona de alerta (11–15): considere refatorar antes que o número continue a subir.
  • Bloqueio operacional (> 15): modularização recomendada — o método já é difícil de testar e arriscado de alterar.
§ 2 Impacto Sistêmico

O que a Ciclomática não captura

A métrica é puramente estrutural. Para a Ciclomática, quatro if independentes têm o mesmo peso de quatro if aninhados — porque o número de caminhos é o mesmo (4 em ambos os casos).

Mas qualquer engenheiro que já leu uma função aninhada em quatro níveis sabe: o custo cognitivo de seguir o fluxo aninhado é muito maior do que ler quatro  funções if lineares. Para esse aspecto, existe uma métrica complementar — a Cognitive Complexity, que é o assunto do próximo post da série.

A Ciclomática, sozinha, responde uma pergunta específica: quantos caminhos esse código tem? E portanto, quantos testes a cobertura mínima exige.

O que acontece com seu codebase quando a Ciclomática sobe

Ciclomática alta numa função isolada é fricção. Quando ela passa de 10 em vários métodos do codebase, vira um passivo sistêmico: o código fica muito mais difícil de entender e testar, o time desacelera mesmo em tarefas que não tocam diretamente as funções complexas, e a probabilidade de introduzir bugs em qualquer mudança aumenta. Três coisas acontecem no time:

Fricção e lentidão na alteração. O dev precisa entender o fluxo inteiro antes de mexer. Métodos com 15+ caminhos exigem que o leitor mantenha em mente todas as combinações possíveis. O tempo de "entender antes de mudar" começa a dominar o de "mudar".

Medo de quebrar o que funciona. Quanto mais caminhos, menor a previsibilidade do efeito colateral de uma mudança. O time desenvolve cautela excessiva. Surge a frase clássica: "estava funcionando, eu nem mexi ali" — geralmente dita logo após mexer ali.

Maior incidência de bugs. Estruturas mal projetadas aumentam a chance de a intenção original do dev não ser refletida na implementação. Mais bifurcações = mais lugares onde a lógica pode divergir do intent.

Comentários decoram a complexidade. Não a removem. A solução é modularizar com foco em localização da mudança.

§ 3 Remediação

A cura é modularização — não comentário

A solução não é "adicionar comentários explicando o fluxo". Comentários decoram a complexidade, não a removem. A solução é modularização com foco em localização da mudança:

  1. Identificar camadas. Mapear os blocos de aninhamento que estão elevando a Ciclomática.
  2. Extrair lógica. Isolar blocos internos em métodos menores e nomeados.
  3. Criar orquestrador. O método principal vira composição: chama os métodos menores na ordem certa.

O resultado: o método orquestrador apresenta Ciclomática baixa (3–5). Cada método extraído também apresenta Ciclomática baixa. O total não diminui — mas a localização da mudança torna-se possível. Você pode mexer em um pedaço sem ler os outros.

§ 4 IA Generativa

O impacto da Ciclomática no uso de IA

A IA generativa (Copilot, Cursor, Claude Code) mantém — e frequentemente piora — o padrão do código em que opera. Não é defeito do modelo: é consequência de como ele toma decisões. Quando você pede "adiciona uma nova regra de classificação aqui", o LLM olha para o método existente, identifica o estilo (ifs sequenciais, condições aninhadas) e o replica. Em código com Ciclomática alta, cada prompt pode elevar a Ciclomática mais um pouco.

O que acontece em código com Ciclomática alta + IA

  • Comportamento adicionado aos lugares já complexos. A IA não decompõe — adiciona à função existente. Métodos com 12 ifs ganham o décimo terceiro; não viram dois métodos de seis cada.
  • Aumento de duplicação. Como o código não é modular, a IA não identifica que uma função semelhante já existe. Gera nova implementação. Cada prompt pode virar, potencialmente, uma nova cópia silenciosa.
  • Maior chance de bugs introduzidos. Em código denso, a IA perde contexto ao longo dos caminhos. Mais bifurcações = mais pontos em que o output do LLM pode divergir do intent.
  • Testes automatizados também ficam complexos. Quando você pede "gera o teste pra essa função", o LLM produz um teste com a mesma estrutura da função — herdando a Ciclomática. Tests difíceis de manter, frágeis para refatoração.
O que fazer agora
Plano operacional · 4 passos
  1. 1 Estabeleça um baseline. Rode a métrica no seu repo hoje. Não tente reduzir tudo de uma vez. Saiba onde você está.
  2. 2 Defina um threshold operacional. Convenção comum: alertar acima de 10, bloquear acima de 15. Ajuste para sua realidade.
  3. 3 Use como gate em PR. Não para bloquear contribuição — para forçar conversa quando o número sobe.
  4. 4 Acompanhe a evolução. O que importa não é o número absoluto. É a tendência. Sobe ou desce a cada release?

Ferramentas que medem Ciclomática

Ferramentas modernas de análise estática medem Ciclomática out-of-the-box: ESLint (com a rule complexity), Checkstyle (Java), radon (Python), gocyclo (Go), lizard (multi-language). plataforma SQA da Codurance integra essa medição às outras quatro métricas desta série em um diagnóstico unificado — útil quando você quer ver a Ciclomática em contexto, não isolada.

Resumo · Pontos-chave
Cinco frases para levar embora.
  • Ciclomática conta caminhos. Cada if, case, for, &&, catch adiciona +1.
  • Atingir a cobertura total de testes significa cobrir todos os pontos da ciclomática.
  • Útil para melhor testabilidade. Um código mais simples permite testes melhores.
  • Modularização é a cura — extrair, nomear, compor.
  • Ajude a IA a te ajudar. Modularização ajuda a IA a codificar com mais qualidade.
Próximo passo na série
Em breve

A Ciclomática responde quantos caminhos. Mas ela não diz nada sobre quão difícil é seguir esses caminhos. Para isso, existe a Cognitive Complexity — e é por isso que duas funções com a mesma Ciclomática podem ter custos completamente diferentes.

Cognitive Complexity
Próximo lançamento da série Code Quality.  Ver índice da série →

How Codurance can help

A Codurance acompanha times de engenharia que querem instrumentar a saúde do código sem se tornarem gestores. Ajudamos Tech Leads e Staff Engineers a definir thresholds operacionais, integrar métricas como Ciclomática em pipelines de CI/CD e estabelecer rituais de revisão que sustentam a qualidade ao longo do tempo.

Se você quer aplicar essas práticas no seu time, entre em contato hoje.

Frequently Asked Questions

1. O que é Cyclomatic Complexity e por que ela importa?

Cyclomatic Complexity é uma métrica que conta o número de caminhos linearmente independentes em uma função. Ela importa porque define objetivamente quantos testes de unidade são necessários para cobrir todos os caminhos de execução — eliminando a subjetividade nas revisões de código.

2. Qual threshold de Cyclomatic Complexity devo usar no meu time?

A convenção mais amplamente adotada é: alertar quando a complexidade passa de 10 e bloquear (ou exigir refatoração) quando passa de 15. Esses valores podem ser ajustados conforme o contexto do time e a natureza do código.

3. A Cyclomatic Complexity substitui a Cognitive Complexity?

Não. As duas métricas respondem perguntas diferentes. A Cyclomatic Complexity mede quantos caminhos existem — e, portanto, quantos testes são necessários. A Cognitive Complexity mede o esforço cognitivo necessário para entender o código. Use ambas: Ciclomática para cobertura de testes, Cognitive para decisões de refatoração.

 

1-4
 1/4 - Ilustração explicando o que é Cyclomatic Complexity, com exemplo de código e destaque de que a métrica indica quantos testes uma função precisa. 
2-4
 2/4 - Diagrama de fluxo mostrando como decisões no código aumentam a complexidade ciclomática, incluindo fórmula e caminhos possíveis. 
3-3
 3/4 - Tabela e explicação interpretando os níveis de complexidade ciclomática e seus impactos em risco e manutenção do código. 
4-1
 4/4 - Recomendações práticas de como usar Cyclomatic Complexity para melhorar código, reduzir complexidade e orientar decisões de engenharia. 
Default image alt text
5 An optional caption for the image that will be added to the gallery. Enter any descriptive text for this image that you would like visitors to be able to read.