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). A 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

    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 →

    Como a Codurance pode ajudar

    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 - Perguntas frequentes

    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.