¿Cuál es la fascinación por las métricas de código? [cerrado]

83

He visto una serie de preguntas relacionadas con 'métricas de código' sobre SO últimamente, y tengo que preguntarme cuál es la fascinación. A continuación se muestran algunos ejemplos recientes:

En mi opinión, ninguna métrica puede sustituir una revisión de código, sin embargo:

  • Algunas métricas a veces pueden indicar lugares que deben revisarse, y
  • Los cambios radicales en las métricas en períodos cortos de tiempo pueden indicar lugares que deben revisarse.

Pero no puedo pensar en una sola métrica que por sí sola siempre indique un código 'bueno' o 'malo'; siempre hay excepciones y razones para cosas que las mediciones no pueden ver.

¿Hay alguna información mágica que se pueda obtener de las métricas de código que he pasado por alto? ¿Están los programadores / gerentes perezosos buscando excusas para no leer código? ¿Se presentan las personas con bases de código heredado gigantes y buscan un lugar para comenzar? ¿Que esta pasando?

Nota: He hecho algunas de estas preguntas en los hilos específicos tanto en las respuestas como en los comentarios y no obtuve respuestas, por lo que pensé que debería preguntar a la comunidad en general, ya que tal vez me esté perdiendo algo. Sería bueno ejecutar un trabajo por lotes de métricas y no tener que leer el código de otras personas (o el mío) nunca más, ¡simplemente no creo que sea práctico!

EDITAR: Estoy familiarizado con la mayoría, si no todas, de las métricas que se están discutiendo, simplemente no veo el sentido de ellas de forma aislada o como estándares arbitrarios de calidad.

Steven A. Lowe
fuente
2
Mi métrica de código para el código C # es the number of StyleCop warnings + 10 * the number of FxCop warnings + 2 to the power of the number of disabled warning types. Solo después de que el valor de esa métrica sea lo más pequeño posible, vale la pena que un humano comience a revisar el código (en mi opinión). En resumen: las herramientas sofisticadas en lugar de las fórmulas simplistas pueden ayudar a mejorar la calidad del código. Sin embargo, esto probablemente esté fuera de tema.
Hamish Grubijan
@Alfred - I just don't see the point of them in isolation or as arbitrary standards of quality.- ¿Quién pensaría en usar métricas de forma aislada o como estándares arbitrarios de calidad?
luis.espinal
@luis esa fue mi edición, basada en varias preguntas que generaron esta pregunta - la respuesta es "administración", principalmente
Steven A. Lowe
+1 para la lista de viñetas de dónde son útiles, creo que es exactamente como lo describe
Variable miserable

Respuestas:

85

Las respuestas en este hilo son un poco extrañas ya que hablan:

  • "el equipo", como "el único beneficiario" de dichas métricas;
  • "las métricas", como si significaran algo en sí mismas.

1 / Las métricas no son para una población, sino para tres :

  • desarrolladores: se preocupan por las métricas de código estático instantáneo con respecto al análisis estático de su código (complejidad ciclomática, calidad de los comentarios, número de líneas, ...)
  • líderes de proyecto: se preocupan por las métricas de código en vivo diarias que provienen de la prueba unitaria, la cobertura del código, las pruebas de integración continua
  • patrocinadores comerciales (siempre se olvidan, pero son los stakeholders, los que pagan por el desarrollo): se preocupan por las métricas de código global semanales en cuanto a diseño arquitectónico, seguridad, dependencias, ...

Todas esas métricas pueden ser observadas y analizadas por las tres poblaciones, por supuesto, pero cada tipo está diseñado para ser mejor utilizado por cada grupo específico.

2 / Las métricas, por sí mismas, representan una instantánea del código, y eso significa ... ¡nada!

Es la combinación de esas métricas y las combinaciones de esos diferentes niveles de análisis lo que puede indicar un código "bueno" o "malo", pero lo que es más importante, es la tendencia de esas métricas lo que es significativo.

Esa es la repetición de esas métricas lo que dará el valor agregado real, ya que ayudarán a los gerentes de negocios / líderes de proyectos / desarrolladores a priorizar entre las diferentes posibles correcciones de código.


En otras palabras, su pregunta sobre la "fascinación de las métricas" podría referirse a la diferencia entre:

  • código "hermoso" (aunque eso siempre está en el ojo del espectador-codificador)
  • código "bueno" (que funciona y puede probar que funciona)

Así, por ejemplo, una función con una complejidad ciclomática de 9 podría definirse como "hermosa", en contraposición a una función larga y enrevesada de complejidad ciclomática de 42.

Pero si:

  • la última función tiene una complejidad constante , combinada con una cobertura de código del 95%,
  • mientras que el primero tiene una complejidad creciente , combinada con una cobertura del ... 0%,

uno podría argumentar:

  • este último representa un código " bueno " (funciona, es estable, y si es necesario cambiarlo, se puede comprobar si sigue funcionando después de las modificaciones),
  • el primero es un código " malo " (todavía es necesario agregar algunos casos y condiciones para cubrir todo lo que tiene que hacer, y no hay una manera fácil de hacer alguna prueba de regresión)

Entonces, para resumir:

una única métrica que por sí sola siempre indica [...]

: no mucho, excepto que el código puede ser más "bonito", lo que en sí mismo no significa mucho ...

¿Hay alguna información mágica que se pueda obtener de las métricas de código que he pasado por alto?

Solo la combinación y la tendencia de las métricas dan la verdadera "visión mágica" que busca.

VonC
fuente
5
El código "hermoso" puede ser más fácil de mantener, y si es así, ¡ESO tiene mucho valor!
Richard T
21

Tenía un proyecto que hice como un trabajo de una sola persona medido por la complejidad ciclomática hace un mes. Esa fue mi primera exposición a este tipo de métricas.

El primer informe que recibí fue impactante. Casi todas mis funciones fallaron en la prueba, incluso las (en mi humilde opinión) muy simples. Logré solucionar el problema de la complejidad moviendo subtareas lógicas a subrutinas, incluso si se han llamado solo una vez.

Para la otra mitad de las rutinas, mi orgullo como programador entró en acción y traté de reescribirlas de una manera que hicieran lo mismo, simplemente más simple y más legible. Eso funcionó y pude llegar al máximo al umbral de complejidad climática del cliente.

Al final, casi siempre pude encontrar una mejor solución y un código mucho más limpio. El rendimiento no se vio afectado por esto (créame, estoy paranoico con esto y verifico el desmontaje de la salida del compilador con bastante frecuencia).

Creo que las métricas son algo bueno si las usa como razón / motivación para mejorar su código. Sin embargo, es importante saber cuándo detenerse y solicitar una concesión por infracción de métricas.

Las métricas son guías y ayudas, no fines en sí mismas.

Nils Pipenbrinck
fuente
1
muy lindo, has logrado expresar una idea muy importante de una manera elegante. Actualmente estoy investigando en el campo de las métricas de software y podría hacer referencia a esto.
Peter Perháč
5
+1 para "Sin embargo, es importante saber cuándo detenerse y solicitar una concesión de infracción de métricas". Tienes tanta razón sobre esto. Es destructivo adherirse dogmáticamente a las métricas.
Shabbyrobe
14

La mejor métrica que he usado es la puntuación CRAP .

Básicamente, es un algoritmo que compara la complejidad ciclomática ponderada con la cobertura de prueba automatizada. El algoritmo se ve así: CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m) donde comp (m) es la complejidad ciclomática del método my cov (m) es la cobertura del código de prueba proporcionada por las pruebas automatizadas.

Los autores del artículo mencionado anteriormente (por favor, léanlo ... vale la pena su tiempo) sugieren una puntuación máxima de CRAP de 30 que se desglosa de la siguiente manera:

Method’s Cyclomatic Complexity        % of coverage required to be
                                      below CRAPpy threshold
------------------------------        --------------------------------
0 – 5                                   0%
10                                     42%
15                                     57%
20                                     71%
25                                     80%
30                                    100%
31+                                   No amount of testing will keep methods
                                      this complex out of CRAP territory.

Como puede ver rápidamente, la métrica recompensa la escritura de código que no es complejo junto con una buena cobertura de prueba (si está escribiendo pruebas unitarias, y debería hacerlo, y no está midiendo la cobertura ... bueno, probablemente disfrutaría escupir al viento también). ;-)

Para la mayoría de mis equipos de desarrollo, me esforcé mucho por obtener la puntuación CRAP por debajo de 8, pero si tenían razones válidas para justificar la complejidad adicional, era aceptable siempre que cubrieran la complejidad con suficientes pruebas. (Escribir código complejo siempre es muy difícil de probar ... una especie de beneficio oculto de esta métrica).

A la mayoría de las personas les resultó difícil inicialmente escribir código que pasara el puntaje CRAP. Pero con el tiempo, escribieron un código mejor, código que tenía menos problemas y código que era mucho más fácil de depurar. De cualquier métrica, esta es la que tiene menos preocupaciones y el mayor beneficio.

RMatthews
fuente
10

Para mí, la métrica más importante que identifica el código incorrecto es la complejidad ciclomática. Casi todos los métodos en mis proyectos están por debajo de CC 10 y los errores se encuentran invariablemente en métodos heredados con CC superior a 30. Un CC alto generalmente indica:

  • código escrito apresuradamente (es decir, no hubo tiempo para encontrar una solución elegante y no porque el problema requiriera una solución compleja)
  • código no probado (nadie escribe pruebas para tales bestias)
  • código que fue parcheado y arreglado varias veces (es decir, plagado de comentarios if y todo)
  • un objetivo principal para la refactorización
Goran
fuente
9

Una buena revisión de código no sustituye a una buena herramienta de análisis estático, que por supuesto no sustituye a un buen conjunto de pruebas unitarias, ahora las pruebas unitarias no son buenas sin un conjunto de pruebas de aceptación ...

Las métricas de código son otra herramienta para poner en su caja de herramientas, no son una solución por derecho propio, son solo una herramienta para usar según sea apropiado (¡con todas las otras herramientas en su caja, por supuesto!).

Scott James
fuente
6

Las personas se sienten atraídas por la idea de formas mecanicistas de comprender y describir el código. Si es cierto, piense en las ramificaciones de la eficiencia y la productividad.

Estoy de acuerdo en que una métrica de "bondad de código" es tan sensata como una métrica de "buena prosa". Sin embargo, eso no significa que las métricas sean inútiles, solo quizás se utilicen incorrectamente.

Por ejemplo, los valores extremos de algunas métricas señalan el camino a posibles problemas. Probablemente no se pueda mantener un método de 1000 líneas . El código con cobertura de código de prueba de unidad cero probablemente tenga más errores que un código similar con muchas pruebas. Un gran salto en el código agregado a un proyecto justo antes del lanzamiento que no es una biblioteca de terceros probablemente sea motivo de atención adicional.

Creo que si utilizamos las métricas como sugerencia, una señal de alerta, quizás puedan ser útiles. El problema es cuando la gente comienza a medir la productividad en SLOC o la calidad en porcentaje de líneas con pruebas.

Jason Cohen
fuente
6

Mi opinión altamente subjetiva es que las métricas del código expresan la fascinación institucional irresistible por poder cuantificar algo inherentemente no cuantificable.

Tiene sentido, en cierto modo, al menos psicológicamente: ¿cómo puedes tomar decisiones sobre algo que no puedes evaluar o comprender? En última instancia, por supuesto, no puede evaluar la calidad a menos que tenga conocimientos sobre el tema (y sea al menos tan bueno como lo que está tratando de evaluar) o le pregunte a alguien que tenga conocimientos, lo que, por supuesto, simplemente devuelve el problema. Un paso.

En ese sentido, tal vez una analogía razonable sería evaluar a los estudiantes que ingresan a la universidad por puntajes SAT, es injusto y pierde todo tipo de sutilezas, pero si necesitas cuantificar tienes que hacer algo.

No digo que crea que es una buena medida, solo que puedo ver la irresistibilidad institucional de la misma. Y, como señaló, probablemente hay algunas métricas razonables (muchos métodos de más de 500 líneas, alta complejidad, probablemente mala). Sin embargo, nunca he estado en un lugar que creyera en esto.

Steve B.
fuente
6

Hay una métrica de código en la que creo.

Estoy trabajando en un gran sistema. Cuando me llega un nuevo requisito, me puse a codificarlo. Cuando termino y soluciono los errores, lo verifico en el sistema de control de versiones. Ese sistema hace una diferencia y cuenta todos los cambios que hice.

Cuanto menor sea ese número, mejor.

Mike Dunlavey
fuente
2
Eso sería cierto considerando que el código anterior fue desarrollado por usted mismo u otro desarrollador con habilidades equivalentes o mejores. Si, por otro lado, el código fue desarrollado por un desarrollador con menos habilidades, un número creciente de líneas en la diferencia (líneas cambiadas + líneas nuevas + muchas líneas eliminadas) en realidad puede significar una mejora en el código a medida que se deshace de código de mala calidad.
Alfred Myers
@Alfred: Claro. Estoy hablando de un mundo ideal y promediado sobre una serie de cambios de requisitos. Aquí hay un ejemplo de lo que estoy hablando, y tiene una curva de aprendizaje: stackoverflow.com/questions/371898/…
Mike Dunlavey
¿Cómo sabe que hizo un buen trabajo si no tiene una línea de base con la que compararlo?
JS
5

Las métricas y las pruebas automatizadas no están destinadas a reemplazar las revisiones de código completas.

Simplemente aceleran las cosas. Con un verificador automático, es muy fácil ver qué convenciones se ha olvidado seguir, que está utilizando los paquetes y métodos designados, etc. Puede ver lo que puede corregir sin usar el tiempo de otras personas.

A los gerentes también les gustan las métricas porque sienten que están obteniendo una cifra exacta de productividad (aunque a menudo ese no es el caso) y deberían poder hacer malabarismos con las personas mejor.

Oli
fuente
5

Las mediciones solo son útiles si:

  • El equipo los desarrolló
  • El equipo estuvo de acuerdo con ellos
  • Se utilizan para identificar un área específica.

En general, cualquier métrica que no se ajuste a eso sufrirá si el equipo la optimiza. ¿Quieres medir líneas de código? ¡Por Dios, mira cuántos pueden escribir! Quieres medir la cobertura del código, caramba, ¡mírame cubrir ese código!

Creo que las métricas pueden ser útiles para identificar tendencias y, de hecho, he visto algunas útiles, como trazar cuándo se rompe la compilación, abandono de código (número de líneas de código que cambian a lo largo del proyecto) y otras cosas. Pero si el equipo no se les ocurre, o no están de acuerdo o no los entienden, es probable que esté en un mundo de dolor.

Cory Foy
fuente
5

Aquí hay algunas métricas de complejidad de stan4j .

Una herramienta de análisis de estructura de clases de eclipse.

Me gusta esta herramienta y las métricas. Trato las métricas como estadísticas, indicadores, mensajes de advertencia. En algún momento debido a algunos métodos o algunas clases realmente tiene alguna lógica complicada que los ha hecho complejos, lo que se debe hacer es vigilarlos, revisarlos para ver si es necesario refactorizarlos o revisarlos cuidadosamente, debido a que normalmente son propensos a errores. También lo utilizo como herramienta de análisis para aprender código fuente, ya que me gusta aprender de lo complejo a lo simple, de hecho incluye algunas otras métricas como Robert C. Martin Metrics, Chidamber & Kemerer Metrics, Count Metrics Pero esta me gusta más.

Métricas de complejidad

Métricas de complejidad ciclomática

Complejidad ciclomática (CC) La complejidad ciclomática de un método es el número de puntos de decisión en el diagrama de flujo de control del método incrementado en uno. Los puntos de decisión ocurren en declaraciones if / for / while, cláusulas case / catch y elementos de código fuente similares, donde el flujo de control no es simplemente lineal. El número de puntos de decisión (código de bytes) introducidos por una sola declaración (código fuente) puede variar, dependiendo, por ejemplo, de la complejidad de las expresiones booleanas. Cuanto mayor sea el valor de complejidad ciclomática de un método, se requieren más casos de prueba para probar todas las ramas del diagrama de flujo de control del método.

Complejidad ciclomática promedio Valor promedio de la métrica Complejidad ciclomática sobre todos los métodos de una aplicación, biblioteca, árbol de paquetes o paquete.

Métricas Fat La métrica Fat de un artefacto es el número de aristas en un gráfico de dependencia apropiado del artefacto. El tipo de gráfico de dependencia depende de la variante métrica y del artefacto elegido:

Fat La métrica Fat de una aplicación, biblioteca o árbol de paquetes es el recuento de bordes de su gráfico de dependencia de subárbol. Este gráfico contiene todos los elementos secundarios del artefacto en la jerarquía del árbol de paquetes, por lo que también incluye paquetes hoja. (Para ver el gráfico apropiado en la Vista de composición, el conmutador de paquetes planos del Explorador de estructuras debe estar deshabilitado. El conmutador Mostrar bibliotecas debe estar habilitado si el artefacto elegido es una biblioteca; de lo contrario, debe deshabilitarse).

La métrica Fat de un paquete es el recuento de bordes de su gráfico de dependencia de unidades. Este gráfico contiene todas las clases de nivel superior del paquete.

La métrica Fat de una clase es el recuento de bordes de su gráfico de miembros. Este gráfico contiene todos los campos, métodos y clases de miembros de la clase. (Este gráfico y el valor de Fat solo están disponibles si el análisis de código se realizó con el miembro de nivel de detalle, no con la clase).

Grasa para dependencias de bibliotecas (Fat - Bibliotecas) La métrica Fat para dependencias de bibliotecas de una aplicación es el recuento de bordes de su gráfico de dependencia de bibliotecas. Este gráfico contiene todas las bibliotecas de la aplicación. (Para ver el gráfico apropiado en la Vista de composición, se debe habilitar la opción Mostrar bibliotecas del Explorador de estructuras).

Grasa para dependencias de paquetes planos (Fat - Paquetes) La métrica Grasa para dependencias de paquetes planos de una aplicación es el recuento de bordes de su gráfico de dependencia de paquetes planos. Este gráfico contiene todos los paquetes de la aplicación. (Para ver el gráfico apropiado en la Vista de composición, la palanca de paquetes planos del Explorador de estructuras debe estar habilitada y la opción Mostrar bibliotecas debe estar deshabilitada).

La métrica Fat for Flat Package Dependencies de una biblioteca es el recuento de bordes de su gráfico de dependencia de paquetes planos. Este gráfico contiene todos los paquetes de la biblioteca. (Para ver el gráfico apropiado en la Vista de composición, los conmutadores de paquetes planos y Mostrar bibliotecas del Explorador de estructuras deben estar habilitados).

Grasa para dependencias de clase de nivel superior (Fat - Unidades) La métrica Fat para dependencias de clase de nivel superior de una aplicación o biblioteca es el recuento de bordes de su gráfico de dependencia de unidades. Este gráfico contiene todas las clases de nivel superior de la aplicación o biblioteca. (Para aplicaciones razonables, es demasiado grande para visualizarse y, por lo tanto, no se puede mostrar en la Vista de composición. Los gráficos de dependencia de unidades solo se pueden mostrar para paquetes).

Clark Bao
fuente
2

Las métricas pueden ser útiles para determinar la mejora o degradación en un proyecto y ciertamente pueden encontrar violaciones de estilo y convenciones, pero no hay sustituto para hacer revisiones de código por pares. No es posible que conozca la calidad de su código sin ellos.

Oh ... y esto supone que al menos uno de los participantes en la revisión de su código tiene una pista.

Steve Moyer
fuente
2

Estoy de acuerdo con usted en que las métricas de código no deben sustituir una revisión de código, pero creo que deben complementar las revisiones de código. Creo que vuelve al viejo dicho de que "no se puede mejorar lo que no se puede medir". Las métricas de código pueden proporcionar al equipo de desarrollo "olores de código" cuantificables o patrones que pueden necesitar más investigación. Las métricas que se capturan en la mayoría de las herramientas de análisis estático suelen ser métricas que se han identificado a lo largo de la investigación en la breve historia de nuestro campo para tener un significado significativo.

Desarrollador SaaS
fuente
2

Las métricas no sustituyen a la revisión de código, pero son mucho más económicas. Son un indicador más que nada.

Andy Lester
fuente
2

Una parte de la respuesta es que algunas métricas de código pueden darle una respuesta inicial muy rápida a la pregunta: ¿Cómo es este código?

Incluso las 'líneas de código' pueden darle una idea del tamaño de la base de código que está viendo.

Como se mencionó en otra respuesta, la tendencia de las métricas le brinda la mayor cantidad de información.

quamrana
fuente
2

Las métricas en sí mismas no son particularmente interesantes. Es lo que haces con ellos lo que cuenta.

Por ejemplo, si estuviera midiendo la cantidad de comentarios por línea de código, ¿cuál consideraría un buen valor? ¿Quién sabe? O quizás lo más importante, todos tienen su propia opinión.

Ahora bien, si recopila suficiente información para poder correlacionar el número de comentarios por línea de código con el tiempo necesario para resolver un error o con el número de errores encontrados que se atribuyen a la codificación, entonces puede comenzar a encontrar un número empíricamente útil. .

No hay diferencia entre usar métricas en software y usar cualquier otra medida de desempeño en cualquier otro proceso: primero se mide, luego se analiza y luego se mejora el proceso. Si todo lo que hace es medir, está perdiendo el tiempo.

editar: En respuesta a los comentarios de Steven A. Lowe, eso es absolutamente correcto. En cualquier análisis de datos, uno debe tener cuidado de distinguir entre relación causal y una mera correlación. Y la selección de las métricas sobre la base de la idoneidad es importante. No tiene sentido intentar medir el consumo de café y atribuir la calidad del código (aunque estoy seguro de que algunos lo han intentado ;-))

Pero antes de que pueda encontrar la relación (causal o no), debe tener los datos.

La selección de los datos a recopilar se basa en qué proceso desea verificar o mejorar. Por ejemplo, si está tratando de analizar el éxito de sus procedimientos de revisión de código (utilizando su propia definición de "éxito", ya sea errores reducidos o errores de codificación reducidos, o un tiempo de respuesta más corto o lo que sea), seleccione métricas que midan la tasa total de errores y la tasa de errores en el código revisado.

Entonces, antes de recopilar los datos, debe saber qué quiere hacer con ellos. Si la métrica es el medio, ¿cuál es el fin?

Andrew Edgecombe
fuente
Estoy de acuerdo, excepto que lo que mides para mejorar es fundamental. Si desea reducir los defectos en un proceso de fabricación, pero todo lo que mide es la cantidad de defectos y la cantidad de café consumido en la sala de descanso, probablemente no llegará a ninguna parte
Steven A. Lowe
en otras palabras, no hay correlaciones establecidas para usar como estándar; ¿Está recomendando el uso de métricas y correlación para establecer un estándar? De ser así, ¿puede demostrar una relación causal o estamos midiendo nuevamente el consumo de café?
Steven A. Lowe
2

No creo que los pequeños cambios en las métricas sean significativos: una función con complejidad 20 no es necesariamente más limpia que una función con complejidad 30. Pero vale la pena ejecutar métricas para buscar grandes diferencias.

Una vez, estaba examinando un par de docenas de proyectos y uno de los proyectos tenía un valor de complejidad máximo de alrededor de 6.000, mientras que todos los demás proyectos tenían un valor de alrededor de 100 o menos. Eso me golpeó en la cabeza como un bate de béisbol. Obviamente, algo inusual, y probablemente malo, estaba sucediendo con ese proyecto.

John D. Cook
fuente
miraste el proyecto? ¿Cuál fue la causa de la gran diferencia en la métrica?
Steven A. Lowe
El proyecto con complejidad 6K comenzó mal escrito, luego empeoró a medida que evolucionaba bajo una presión extrema.
John D. Cook
1

Somos programadores. Nos gustan los números.

Además, ¿qué vas a hacer, NO describir el tamaño del código base porque "las líneas de métricas de código son irrelevantes"?

Definitivamente hay una diferencia entre un código base de 150 líneas y uno de 150 millones, por tomar un ejemplo tonto. Y no es un número difícil de conseguir.

Thomas David Baker
fuente
1
hay una diferencia, uno tiene más líneas de código. ¿Y qué? Eso no dice nada sobre la calidad del software ...
Steven A. Lowe
2
Sé en cuál elegiría trabajar a continuación ;-)
quamrana