Icono del sitio Alexander Andrade

Las cinco métricas de código para mejorar la calidad del software

Comprender el estado de la base código del software puede ayudarle a enfocar mejor sus esfuerzos de pruebas. El código es comunicación y guarda dentro de si el Know-How de la empresa, por lo cual debemos realizar mayores esfuerzos para que este sea claro, que otros desarrolladores lo puedan entender y darle evolución.

Las cinco métricas de código principales para ayudarlo a realizar mejores pruebas

Las métricas de análisis estático pueden ayudar a los Ingenieros de Calidad de Software a concentrarse en áreas específicas del código. Algunos testers pueden sentirse intimidados por las métricas de código, pero comprender cómo funcionan las métricas es muy diferente a desarrollar software en sí; son mas bien una herramienta vital para ayudar a educar a todo el equipo sobre cómo debería ser un buen software.

En primer lugar, algo de claridad sobre los términos que se utilizan a continuación:

Las herramientas de análisis estático examinan el código o sistema y miden preocupaciones específicas durante el análisis. Con el tiempo, la industria ha descubierto pautas generales en torno a varias métricas que indican si esa medida en particular se alinea o no con los rangos generalmente aceptados. Cada herramienta de análisis moderna proporcionará medidas y alguna referencia en cuanto a los valores estándar aceptados para esa métrica.

No. No existen «mejores prácticas» en torno a tales métricas, ya que no existen las «mejores prácticas». Los resultados de las métricas deben interpretarse en el contexto de las prácticas generales y la madurez de la organización.

Hay una gran cantidad de métricas disponibles para el software de medición. Este artículo se centra en los cinco de las más útiles. Se enumeran a continuación en orden inverso.

Comentarios en el código

Qué es: uso excesivo de comentarios en el código.

Los comentarios en código pueden ser un tema controvertido. Las prácticas de desarrollo de la vieja escuela alentaron una gran cantidad de comentarios, y algunos académicos exigieron un comentario para cada declaración, o sea, cada rengón.

Esto llevó a prácticas como:

int index = 0; //set index to 0

Que no hace nada más que basura con información sin sentido que se puede quedar desactualizada fácilmente, por ejemplo:

int index = 1; //set index to 0

Tales desconexiones causan grandes dificultades cuando alguien vuelve a leer el código como parte de una corrección de errores o una mejora de funciones. ¿Es correcto el código? ¿Se suponía que el índice estaba establecido en un valor de «1»? ¿O el comentario fue correcto y el índice debería haberse establecido en cero?

Las prácticas de software modernas prefieren centrarse en buenas prácticas de nomenclatura en el código mismo. Los comentarios deben reservarse para explicar una sección con una lógica muy difícil o reglas específicas de dominio. Los bloques de comportamiento crítico y confuso deben extraerse en métodos bien nombrados que aclaren la intención. Los comentarios breves, concisos y aplicables deben limitarse a explicar el * por qué *, no el cómo.

Por ejemplo, aquí hay un ejemplo no funcional.

public boolean IsShippingTypeValid(Product product,
Order custOrder,
IShippingLookup lookup){
// Call lookup system to check shipping. Reject if
// too heavy or bulky for specific destination.
// See IShippingLookup for more details on rules.

return lookup.IsDestinationValidForProduct(custOrder.Destination, product);
}

Un poco a tono con lo que es Clean CodeMartin Fowler dice:

Cualquiera puede escribir código que una máquina entiende. Los buenos programadores escriben código que los humanos pueden entender

Martin Fowler

Por eso, un comentario puede ser un indicativo de que falta mayor claridad al escribir el código. Ya no estamos en los años 80s o 90s donde debíamos escribir el menor número de líneas por temas de tamaños de disco o rendimiento, ahora es aceptable que escribamos unas cuantas líneas de más con tal de lograr una mejor comunicación. Por ejemplo:

// if during work hours
if (currentTime.hours >= 9 && currentTime.hours <= 17)

Lo más correcto es hacer una función con un nombre disiente para reemplazar este código

if ( currentTime.isDuringWorkHours() )

Este ejemplo también hace uso del principio “Tell, dont ask” (dilo, no lo preguntes) donde se centraliza dentro de la clase “currentTime” todo lo relacionado con tiempo y no se hacen cálculos en el resto del programa que tendrían «tocarse» cuando haya una actualización de lo que corresponde al horario laboral.

Cómo usarlo: mire los informes de métricas de clases y métodos con una gran cantidad de comentarios. Abra esas clases en su editor favorito y busque desconexiones entre lo que hace el código y lo que dicen los comentarios. Si hay confusión y desconexiones, hable con un desarrollador para ver si puede encontrar claridad. Mire las pruebas automatizadas para mayor claridad. Cree y ejecute escenarios de prueba / cartas exploratorias para ejercitar esa área específica de funcionalidad.

NOTA: por definición, tanto el código (variables y más) como los comentarios deben estar en inglés.

Líneas de código

Qué es: clases, módulos, métodos, bloques demasiado largos.

Las clases, los bloques o los métodos enormes pueden indicar un área de código que tiene demasiadas responsabilidades y comportamientos. Las secciones largas de código son generalmente muy confusas, difíciles de probar y muy difíciles de mantener.

Cómo usarlo: busque clases y métodos largos. ¿Son esos bloques confusos y tienen responsabilidades mixtas, como crear conexiones de datos mientras se crean hilos y se actualiza la interfaz de usuario? Vea lo que puede discernir del código y asóciese con un desarrollador para discutir las áreas de riesgo de esos grandes bloques. Nuevamente, cree y ejecute sesiones de prueba en función de lo que descubra.

Nota: se aconseja que el tamaño de una clase o método no supere una “pantalla”, o sea, sin hacer scroll se debería ser capaz de ver todo el código. En términos prácticos, se recomiendan tamaños no superiores a 25 o 40 líneas, dependiendo de temas como fuentes y tamaños. En la Google Java Style Guide (Guía de Google de estilos para Java) puede ver mas recomendaciones.

Acoplamiento

Qué es: el acoplamiento es una medida bidireccional. De acuerdo con la Wikipedia, el acoplamiento es la forma y nivel de interdependencia entre módulos de software; una medida de qué tan cercanamente conectados están dos rutinas o módulos de software. Es una medida de las dependencias entrantes (aferente) y salientes (eferente).

Los componentes con muchos acoplamientos están en riesgo de dos formas diferentes. Si muchos otros componentes dependen del que está examinando, cualquier cambio en el componente actual corre el riesgo de romper los otros. Por el contrario, si el componente actual depende de muchos componentes externos, entonces el riesgo de que el componente actual se rompa, ya que muchos otros componentes pueden afectar al actual.

Cómo usarlo: busque un acoplamiento alto en cualquier dirección. Cree cambios importantes dentro de los componentes externos y vea cómo reacciona el componente actual. Haga lo contrario para probar los componentes salientes. Examine qué tan bien están protegidas esas áreas con una buena unidad automatizada y pruebas de integración. Apuntale eso según sea necesario. Explore las pruebas de API de los distintos componentes para comprender mejor los problemas de calidad.

NOTA: es muy bueno revisar además del acoplamiento, todo lo relacionado con los principios SOLID para lograr la tan anhelada “alta cohesión y bajo acoplamiento”.

Rotación

Qué es: La “Rotación” (churn en inglés) es la cantidad de ediciones en un archivo de código fuente. Por lo general, se mide por el número de confirmaciones al control de código fuente (GitHub, por ejemplo) para un archivo específico.

Los archivos con una alta rotación indican áreas específicas del sistema que se someten a muchas actualizaciones. Si bien hay excepciones, los archivos que se actualizan con frecuencia son normalmente un indicador de que existen problemas de calidad dentro de ese archivo. Estos problemas de calidad podrían ser sencillos: una sección difícil y frágil del sistema que requiere muchas correcciones de errores. Los problemas de calidad también pueden ser más sutiles: una clase o componente mal diseñado que es muy difícil de modificar cuando se intenta ampliar o modificar otras áreas del sistema.

Cómo usarlo: Busque áreas con alta rotación. Haga un análisis concienzudo sobre esas clases, módulos, paquetes, lo que sea. Al igual que con el alto acoplamiento, asegúrese de que las pruebas de regresión automatizadas sean sólidas. Constrúyalos en un enfoque de riesgo / valor cuando sea necesario. Refuerce las pruebas en áreas de alta rotación a través de pruebas de fuzzing (inserción automatizada de datos aleatorios en el programa) y otros enfoques similares de alto impacto.

Complejidad

Qué es: La complejidad ciclomática es un recuento del número de caminos separados a través de un bloque de código. Cuantas más rutas, más difícil es probar y mantener el código. Las sentencias IF / ELSE anidadas, múltiples bloques SWITCH / CASE y otras construcciones similares conducen rápidamente la complejidad ciclomática a reinos peligrosos.

La complejidad ciclomática es mi métrica número uno cuando intento tener una idea rápida de la calidad y el estado de una base de código. Los números de complejidad altos o incluso escandalosos indican muchas cosas sobre el nivel de madurez del equipo, el pensamiento de diseño y las habilidades simples de ingeniería de software. Ninguno de esos indicadores es bueno, por cierto.

La alta complejidad aplasta la capacidad de un equipo para expresar claramente el comportamiento previsto de un bloque, y hace que la relectura de ese bloque de código sea una marcha penosa, tortuosa y propensa a errores. Además, los estudios han demostrado una correlación directamente proporcional entre la alta complejidad y las altas tasas de defectos.

Cómo usarlo: Comience de arriba hacia abajo con los infractores más atroces: bloques con métricas de complejidad muy por encima de lo normal. Dedique algo de tiempo y superponga las Métricas de Rotación con las secciones de mayor complejidad. Vea si puede determinar el historial de errores (abiertos y cerrados) para esos mismos bloques. Con esos datos en la mano, diríjase y realice esfuerzos de prueba en las áreas más riesgosas de ese diagrama de Venn metafórico.

Conclusión

Las métricas de análisis de código estático pueden proporcionar a los testers una gran cantidad de información sobre el estado general de la base de código. Las métricas pueden ayudar a informar sobre áreas sólidas que no necesitan mucha atención, y ciertamente pueden ayudar a los QA a determinar en qué áreas dedicar su valioso tiempo.

Fuentes

GuRock – Top Five Code Metrics to Help You Test Better

Jesús Rodríguez – Solid no es un juego de jenga

Baeldung – Clean Code: Comments

Imagen por Kevin Ku en Unsplash

Author: Alexander Andrade

Ingeniero de Sistemas, MBA y Especialista en Gerencia de Proyectos Tel: +57-317-241-5118
Salir de la versión móvil