Pega código y obtén la complejidad ciclomática de McCabe por función, con cada punto de decisión indicado por línea y comparado con límites publicados.
No se sube nada: el recuento se ejecuta en tu navegador.
Empieza en 1 y suma uno por cada decisión. NIST SP 500-235, sección 4.1
| Construcción | Suma | Por qué |
|---|---|---|
| if | 1 | Una rama nueva a través del código. |
| else if / elif | 1 | Es su propia decisión, y solo se evalúa cuando la anterior fue falsa. |
| for, foreach, while, do-while | 1 | La condición del bucle decide si el cuerpo se ejecuta otra vez. |
| etiqueta case | 1 | Un switch de k vías suma uno menos que su número de aristas salientes, es decir una por etiqueta case. |
| catch / except | 1 | Cada manejador es un camino distinto de salida del bloque try. |
| condicional ternario | 1 | Una expresión condicional es una decisión, igual que un if. |
| AND de cortocircuito | 1 | La evaluación en cortocircuito hace que el operando derecho pueda no ejecutarse nunca, así que es una rama. |
| OR de cortocircuito | 1 | Por la misma razón que el AND: el operando derecho es condicional. |
| operador de coalescencia nula | 1 | El valor de la derecha solo se evalúa cuando el de la izquierda es nulo. |
| operador condicional nulo (?.) | 0 | Aquí no se cuenta. Hace cortocircuito, pero protege un acceso a un miembro en lugar de elegir entre dos cálculos, así que un a?.b?.c idiomático sumaría tres a una función que casi cualquier revisor consideraría sin decisiones. Las herramientas no coinciden: lizard sí lo cuenta. El analizador de tu compilación puede informar un número algo mayor para cadenas como esta. |
| un else simple | 0 | Es la rama falsa de un if que ya se contó. |
| el default de un switch | 0 | Es la rama por omisión del switch, ya cubierta por las etiquetas case. |
| la palabra clave switch en sí | 0 | El switch no es la decisión; sus etiquetas case lo son. |
| una sentencia return | 0 | Los puntos de salida no cambian la complejidad ciclomática. Diez returns o uno, el recuento es el mismo. |
Los umbrales que los estándares y las herramientas realmente especifican
| Fuente | Límite | Se aplica a |
|---|---|---|
| McCabe 1976 / NIST SP 500-235, sección 2.5 | 10 | Por módulo. La sección se titula Limitar la complejidad ciclomática a 10. |
| NIST SP 500-235, tolerancia superior | 15 | Solo para proyectos con personal experimentado, diseño formal, programación estructurada y un plan de pruebas completo. |
| NASA NPR 7150.2, sección 3.7.5 (SWE-220) | 15 | Componentes críticos para la seguridad. Todo exceso debe revisarse y aprobarse con justificación por escrito. |
| Regla S1541 de SonarQube, parámetro por omisión | 10 | Por método. Ten en cuenta que la regla no está activada en el perfil por omisión de SonarQube. |
| Regla complexity de ESLint, valor por omisión | 20 | Por función. Ten en cuenta que la regla está desactivada salvo que la actives. |
El recuento es léxico, no un análisis sintáctico completo: se ignoran las cadenas y los comentarios, pero macros poco habituales, código generado o un fragmento sintácticamente incompleto pueden alterar el resultado. Trátalo como una ayuda para la revisión y usa el analizador de tu propia compilación como cifra de referencia.
También podrías encontrar útiles estas calculadoras
Pega tu código y obtén su Big-O de tiempo y espacio
Cobertura por criterio, comparada con requisitos que sí podemos citar
Cuenta SLOC, comentarios y líneas en blanco y estima el esfuerzo
Mide el rendimiento DevOps con cuatro métricas clave
Pega una función o un archivo completo y esta calculadora cuenta sus puntos de decisión por ti, informa la complejidad ciclomática de cada función que encuentra y te muestra la línea en la que se contó cada decisión. Lee Python, JavaScript, TypeScript, Java, C, C++, C# y Go, y el recuento se ejecuta enteramente en tu navegador. Si prefieres trabajar desde un grafo de flujo de control o desde un recuento que ya tienes, ambos modos también están disponibles.
La complejidad ciclomática, introducida por Thomas J. McCabe en 1976, cuenta los caminos linealmente independientes a través de un módulo. Una función sin ramificaciones tiene complejidad 1; cada decisión suma uno. El número importa por dos razones prácticas: es exactamente el número de pruebas que necesita un conjunto de pruebas de caminos base, y guarda relación con lo difícil que resulta leer y modificar el código. Contar puntos de decisión y leer los números de un grafo de flujo de control son dos rutas al mismo resultado.
Fórmula de McCabe
Pega la función que estás revisando y obtén un número más el motivo línea por línea, lo que convierte una discusión subjetiva sobre complejidad en un recuento verificable.
Usa la complejidad de cada función como el tamaño exacto de su conjunto de pruebas de caminos base, y como el techo de cuántas pruebas necesitará la cobertura completa de ramas.
Antes de activar una puerta de complejidad, pasa tus peores archivos por aquí y observa qué rechazaría un límite de 10, 15 o 20, para que el umbral que elijas sea uno que el equipo pueda cumplir.
NASA NPR 7150.2 exige que los componentes críticos para la seguridad estén en 15 o menos, y que todo exceso se apruebe por escrito. Mide por función para saber qué componentes necesitan esa justificación.
El número de complejidad es exactamente cuántas pruebas necesita un conjunto de caminos base, y una cota superior de cuántas necesita la cobertura completa de ramas: NIST SP 500-235 señala que cubrir todas las aristas suele lograrse con menos caminos. Saber qué cota se aplica evita sobredimensionar un plan de pruebas.
Un promedio por archivo esconde el problema. Esta calculadora informa cada función por separado y las ordena de peor a mejor, así que la única función que acumula la complejidad es la primera fila y no un número que tengas que buscar.
Los límites se repiten sin indicar su procedencia. Cada umbral aquí nombra un documento: el 10 original de McCabe, el 15 que NIST admite bajo condiciones expresas, el 15 de la NASA para código crítico para la seguridad, y los valores por omisión de las reglas de SonarQube y ESLint.
Los umbrales de integración continua solo funcionan si el número sobre el que actúan es el de la peor función, no un total por archivo. Ver el desglose por función te dice qué rechazaría hoy una puerta fijada en 10 o en 15.
Exactamente 10 para pruebas de caminos base: NIST SP 500-235 establece que el número de caminos de prueba que requiere un módulo es exactamente su complejidad ciclomática. Para la cobertura de ramas es una cota superior, no un mínimo: la sección 2.4 de NIST muestra un módulo de complejidad 3 cuyas aristas quedan todas cubiertas por 2 de los 3 caminos base, y señala que cubrir todas las aristas suele lograrse con menos caminos. Para la cobertura completa de caminos la complejidad es una cota inferior, y un bucle puede hacer que el número real sea ilimitado.
No. Una función con diez returns y otra con uno tienen la misma complejidad ciclomática si toman las mismas decisiones. Un grafo de flujo de control con s puntos de salida necesita s aristas virtuales para quedar fuertemente conexo, de modo que v = E + s - N + 1, y al sustituir E = N - s + π queda π + 1 para cualquier s. NIST SP 500-235 establece v(G) = π + 1 sin ningún término de puntos de salida en sus 124 páginas, y los analizadores de referencia coinciden. Puede que veas citada M = π - s + 2 para programas con varias salidas; asume otra convención de grafo y no coincide con lo que informan las herramientas de producción.
Cada if, else if o elif, for, foreach, while, do-while, etiqueta case, catch o except, condicional ternario, y cada operador de cortocircuito &&, || o ??. Empieza en uno y suma uno por cada uno. Un else simple no suma nada, porque es la rama falsa de un if que ya se contó, y el default de un switch tampoco por la misma razón.
Porque la evaluación en cortocircuito convierte cada operando en una rama. En if (a && b) la comprobación de b solo se ejecuta cuando a es verdadero, así que hay tres caminos por la sentencia, no dos. Por eso extraer una expresión booleana larga a un método con nombre reduce de verdad la complejidad medida de la función de la que salió.
Por función. La complejidad ciclomática se define para un módulo con un solo punto de entrada, y todos los límites publicados se expresan por método o por función. Un total por archivo indica cuánta ramificación contiene el archivo, lo que sirve para priorizar, pero no es el número que aplica ningún estándar. Esta calculadora informa ambos y toma como número principal el de la peor función.
No. La complejidad ciclomática cuenta caminos y trata todas las decisiones como iguales. La complejidad cognitiva, que usa el perfil por omisión de SonarQube, pondera más las decisiones anidadas e ignora algunas estructuras que añaden caminos pero no confusión, como un switch largo. Responden preguntas distintas: la ciclomática indica cuántas pruebas debes escribir, la cognitiva estima lo difícil que es leer el código.
Diez es el valor por omisión defendible. NIST SP 500-235 titula su sección Limitar la complejidad ciclomática a 10 y afirma que el límite original cuenta con evidencia significativa a su favor, señalando además que proyectos con personal experimentado, diseño formal, programación estructurada y un plan de pruebas completo han usado con éxito límites de hasta 15. La NASA fija en 15 el techo de los componentes críticos para la seguridad, con exenciones por escrito. La regla de SonarQube usa 10 por omisión y la de ESLint, 20.
Extrae cada condición compuesta a una función predicado con buen nombre, sustituye los condicionales anidados por cláusulas de guardia con retorno temprano, lleva un switch largo a polimorfismo o a una tabla de consulta, y divide en dos toda función que haga dos trabajos. Ten en cuenta que añadir returns no ayuda y quitarlos no perjudica: solo eliminar decisiones baja el número.