En Mi Local Funciona

Technical thoughts, stories and ideas

Las tripas de SonarQube: Métricas y cómo calcula el Rating (Parte 2)

Publicado por Javier Larios Calleja el

QASonarQube

En este post, tras ver en la parte 1 como montar SonarQube de forma rápida sobre Azure, vamos a verle las tripas a SonarQube y a entender por qué y cómo categoriza los proyectos y cada métrica con un determinado Rating.

Trataremos estas métricas:

  • Líneas de código
  • Issues, tipos y severidades
  • Reglas
  • Cobertura
  • Porcentaje de código duplicado
  • Líneas/Bloques duplicados
  • Complejidad
  • Deuda Técnica
  • Rating --> SQALE
  • Quality Gate

Líneas de Código

Se realiza un conteo del número de líneas físicas que contienen al menos un carácter y que no son un espacio en blanco, una tabulación o un comentario.

Para ver el dato pulsaremos sobre el Proyecto - Project Information > Lines of Code:

Si accedemos a 'Measures' mediante el submenú o bien pulsamos sobre 'Lines of Code' del menú anterior, veremos dicho conteo segregado por Lenguajes:

Issues, tipos y severidades

El término issue se atribuye a la unidad de trabajo para realizar una mejora.

Posteriormente ese issue, es clasificado en tipos por SonarQube como:

  • Vulnerability: Indica que se ha descubierto un problema que afecta la seguridad de la aplicación y que debe solucionarse de inmediato.
  • Bug: Un error.
  • Security Hotspot: Se resalta un fragmento de código sensible a la seguridad, pero es posible que la seguridad general de la aplicación no se vea afectada. Depende del desarrollador revisar el código para determinar si se necesita o no una corrección para asegurar el código.
  • Code Smell: Código que dificulta el mantenimiento (huele mal).

El detalle de los issues y las reglas asociadas, se puede encontrar en
https://rules.sonarsource.com.

Finalmente, son segregados según la severidad:

  • Blocker: Error con una alta probabilidad de afectar el comportamiento de la aplicación en producción.
  • Critical: Urge su corrección aunque no suponga un afectación al comportamiento de la aplicación en producción o porque es una falla de seguridad de impacto alto.
  • Major: Defecto de calidad que puede afectar enormemente a la productividad del desarrollador.
  • Minor: Defecto de calidad que puede afectar ligeramente la productividad del desarrollador.
  • Info: Ni un error ni un defecto de calidad, solo un hallazgo o una mejora.

Reglas

Accediendo al menú superior mediante 'Rules'.

Las reglas configuradas aquí son las que serán auditadas en el IDE del desarrollado. SonarLint es explicado en la Parte 3 de esta serie de post

Por defecto, SonarQube tendrá en su motor de análisis las publicadas oficialmente, pero pueden ser suprimidas, modificadas o no aplicadas.

Señalando cada Regla se puede actuar sobre ella, y se puede consultar su descripción y detalle.

Cobertura

Indica gráficamente cuántas líneas del código (LoC) están cubiertas por pruebas unitarias.

SonarQube no ejecuta las pruebas ni genera informes. Solo importa informes generados previamente.

De ahí, que en la parte 3 de esta serie de post tengamos que emplear Jest en JavaScript, en caso de Java sería necesario JaCoCo y JUnit.

En el Dashboard principal y en el submenú 'Overview' tendremos detalle sobre la cobertura:

Si pulsamos sobre la métrica nos da información detallada y los ficheros afectados:

En el menú de la izquierda, nos da información del resultado de la ejecución de las pruebas unitarias:

Además, y muy importante, podemos comprobar su evolución mediante gráficas de evolución e histórico mediante snapshots:

Para poder disponer de histórico, es necesario que el SonarQube sea productivo y disponga de una Base de Datos y por ende, de persistencia

Si accedemos a un fichero, en este caso Java, podemos ver como Sonar señala mediante una barra roja las líneas que no tienen cobertura y un icono que indica si dicha línea o fragmento tiene un tipo de issue:

Porcentaje de código duplicado

Es una de las métricas que mejor indica qué grado de malas prácticas tenemos instaurado en nuestro proyecto.
SonarQube realiza este análisis con el objetivo de encontrar líneas, bloques o ficheros duplicados en el código fuente de los proyectos.

Si el código se tiene que repetir, debería estar encapsulado en un método de una clase. Esto permite reducir el tamaño del código y facilita el mantenimiento ya que cualquier cambio posterior sólo se tiene que hacer en un sitio localizado.

Como es una métrica principal se consultará desde el dashboard principal y clicando sobre ella podremos profundizar en la información analizada.

Líneas/Bloques duplicados

Si accedemos al fichero con código duplicado y posicionando el cursor sobre la barra gris de la izquierda, nos mostrará un PopUp con las líneas o bloque publicada. Si pulsamos en dicha información nos mostrará más información en detalle.

Líneas:

Bloques:

La densidad de duplicación de código debe ser cercana a inferior a 1.

¿Que estrategias seguir para resolver la duplicación de código?

  • Extraer métodos mediante un método utilitario.
  • Elevar propiedades cuando hay 2 clases que tienen las mismas propiedades y pueden elevarse a una superclase. Posteriormente realizar la herencia.
  • Extraer clase: Cuando hay mucho métodos utilitarios que podemos almacenar en una sola clase que sea invocada por el resto de una manera común.

Complejidad

Uno de los valores más conocidos es el llamado Número de Complejidad Ciclomática (CCN, Cyclomatic Complexity Number), que también es conocido como la métrica McCabe.

Se trata de contar el número de sentencias condicionales ‘if’, ‘for’, ‘while’,y otros, en un método. Cada vez que el flujo de control del código de un método se bifurca, el contador ciclomático se incrementa en uno. Cada método tiene un valor mínimo de uno por defecto, excepto para los métodos ‘get’ y ‘set’ en cuyo caso no se tienen en cuenta para la complejidad.

La complejidad ciclomática se basa en el diagrama de flujo determinado por las estructuras de control de un determinado código. De dicho análisis se puede obtener una medida cuantitativa de la dificultad de crear pruebas automáticas del código y también es una medición orientativa de la fiabilidad del mismo.

El resultado obtenido en el cálculo de la complejidad ciclomática define el número de caminos independientes dentro de un fragmento de código y determina la cota superior del número de pruebas que se deben realizar para asegurar que se ejecuta cada sentencia al menos una vez.

Ejemplo de grafo de flujo de control. El programa empieza ejecutándose en el nodo rojo y sale en el azul. Este grafo tiene 9 aristas, 8 nodos y un componente conexo. Por lo que la complejidad ciclomática es 9-8+21=3*

Nos dirigimos a 'Measures' – 'Complexity' (Menú izquierdo) y elegir vista por lista.

Si accedemos al fichero implicado, al igual que con métricas anteriores, Sonar nos señalará donde se encuentra la complejidad:

Existen los siguientes Niveles de Complejidad con un Riesgo asociado directamente al esfuerzo necesario para el mantenimiento:

  • 1 - 10: Sin riesgo
  • 11 - 20: Riesgo Moderado
  • 21 - 50: Riesgo Alto
  • > 50: Es necesario/imprescindible refactorizar.

Deuda Técnica

Esta es una de las métricas más en boca y con más importancia.

Si un equipo sólo se fija en esta métrica sobre las demás, tendrá un alto porcentaje para que su proyecto disponga de un buen código.

Se entiende por deuda técnica el esfuerzo futuro que se debe realizar para arreglar defectos, vulnerabilidades y problemas de mantenimiento que en su momento se introdujeron en los sistemas por alguna urgencia, plazo de entrega ajustado o falta de conocimiento. Al igual que pasa con la deuda financiera, la deuda técnica acarrea intereses, lo que quiere decir que cuanto más tiempo se deja pasar desde que se introducen los problemas hasta que se aborda su resolución, mayor será el esfuerzo necesario para arreglarlos.

También al igual que ocurre con la deuda financiera, un poco de deuda técnica de forma controlada en ocasiones es necesaria y puede servir como impulso para probar rápidamente un nuevo evolutivo de nuestros sistemas, facilitar la implantación de una idea de negocio o reducir el tiempo de una salida a Producción. Lo importante en este caso es saber cuánta deuda técnica estamos introduciendo, dar visibilidad al equipo sobre ella y trazar unas pautas y un plan para su control.

Una excesiva deuda técnica será un factor determinante en el futuro a la hora de generar sobrecoste en la implementación de nuevas funcionalidades, llegando en casos extremos a tener que descartarse la implantación de esas funcionalidades que aportarían valor a los procesos y los usuarios, por motivos presupuestarios o tecnológicos.

SonarQube nos la mostrará por ello en su dashboard principal:

Si profundizamos, nos mostrará la medida de deuda técnica por fichero:

Como se puede ver, Sonar calcula la deuda técnica en una escala de esfuerzo temporal, es decir, cuánto se tardaría en solucionar los problemas existentes mediante un variable configurable (15 mins / 30 mins, etc).

A la izquierda nos muestra una métrica llamada 'Debt Ratio', la cual indica la prioridad para la resolución de la deuda técnica.
Es la proporción entre la deuda técnica total (la que tenemos) Vs deuda técnica posible (el peor escenario).

Otra métrica, el Rating de Deuda Técnica, lo que viene siendo la Calificación de nuestro código:

¿Cómo cambiamos el coste de la deuda técnica?

Accedemos a 'Administration' del menú superior - Configuration (submenú) y 'Technical Debt':

Para saber que coste de deuda técnica tiene cada tipo de issue, lo veremos en la descripción de cada regla:

Recordad que la deuda técnica es la suma de todos los costes de los tipos de issues o problemas detectados:

  • Código duplicado.
  • Complejidad ciclomática.
  • Vulnerabilidades.
  • Baja cobertura de tests unitarios.
  • Uso de métodos obsoletos.
  • Ausencia de estilo de programación.
  • Y en general cualquier defecto no funcional detectable mediante análisis estático de código.

Rating --> SQALE

SQALE (Software Quality Assessment based on Lifecycle Expectations), es un modelo de calidad creado para dar soporte a la evaluación de aplicaciones de software, el cual nos aporta el Rating o calificación (A, B, C, D y E) del proyecto a nivel de código.

La calificación para una característica concreta y un artefacto concreto es la distancia que existe entre la calidad actual del proyecto Vs la calidad deseada al final de desarrollo, o dicho de otra forma, la diferencia entre coste estimado de corregirla Vs la estimación del coste de desarrollo de ese artefacto.

  • A --> Calidad excelente
  • B --> Calidad notable
  • C --> Calidad insuficiente
  • D --> Calidad baja
  • E --> Calidad muy baja

Maintainability / Mantenibilidad: Capacidad del producto software para ser modificado efectiva y eficientemente, debido a necesidades evolutivas, correctivas o perfectivas.

Se calcula de la siguiente manera:

  • A: < 5%
  • B: 6% - 10%
  • C: 11% - 20%
  • D: 21% - 50%
  • E: > 50%

Se muestran vistas por su cumplimiento según el fichero:

Vista de gráfico de burbujas:

Vita por contenido del fichero a nivel de código:

Reliability / Fiabilidad: Capacidad de un sistema o componente para desempeñar correctamente las funciones especificadas. Es directamente proporcional al coste de solucionar los issues que provocan que el sistema no sea confiable. Por ello, el rating se realiza en base a las Bugs encontrados.

Se calcula de la siguiente manera:

  • A: Sin Bugs
  • B: 1 Bug Minor
  • C: 1 Bug Major
  • D: 1 Bug Crítico
  • E: 1 Bug Blocker

Vista de gráfico de burbujas:

Security / Seguridad: Grado de protección de la información y los datos de manera que personas o sistemas no autorizados no puedan leerlos o modificarlos. Directamente proporcional a la capacidad que tiene el sistema para reducir el número de los ataques. Por ello, el rating se realiza en base a las vulnerabilidades encontrados.

Se calcula de la siguiente manera:

  • A: 0 Vulnerabilidades
  • B: 1 Vulnerabilidad Minor
  • C: 1 Vulnerabilidad Major
  • D: 1 Vulnerabilidad Critical
  • E: 1 Vulnerabilidad Blocker

Vista de gráfico de burbujas:

Security Review / Revisión de Seguridad: Como se ha comentado anteriormente, un HotSpot es una posible evidencia de una vulnerabilidad de seguridad, que previamente debe ser revisada y decidir si es, o no una vulnerabilidad que necesita una solución. Por ello, el rating de realiza en base al número de hotspots revisados.

Se calcula de la siguiente manera:

  • A: > 80%
  • B: 70% - 80%
  • C: 50% - 70%
  • D: 30% - 50%
  • E: < 30%

Vista por ficheros:

Quality Gates

Es un conjunto predefinido de criterios de calidad de código definidos en SonarQube que un proyecto debe cumplir con el fin de pasar de una etapa de su ciclo de vida a la siguiente.

SonarQube proporciona por defecto una Quality Gate llamada 'Sonarway' con una condiciones base. Se centra en mantener limpio el código nuevo, en lugar de gastar mucho esfuerzo en corregir el código antiguo.

Es posible modificar o crear nuevas Quality Gates si el proyecto es algo especial (por lenguaje, complejidad, etc.), o bien queremos parametrizar las condiciones de Quality Gates para:

  • Modificar valores de cumplimiento.
  • Incluir / Extraer condiciones.
  • Para todo el código / Nuevo código.

Para definir la Quality Gate, se debe seleccionar:

  • Una medida, es decir una métrica KPI analizada por Sonar.
  • Un operador de comparación: <, >.
  • Un valor de error.

Cualquier usuario (incluso usuarios anónimos) pueden acceder a los Quality Gates. Todos los usuarios pueden ver todos los aspectos de una puerta de calidad pero sólo pueden realizar cambios los usuarios con permiso para 'Administer Quality Profiles and Gates'.

Por ello, un administrador de proyecto puede elegir qué Quality Gate aplica a su proyecto:

Finalmente, veremos el estado actual del Quality Gate en el dashboard del proyecto:

Además, SonarQube permite exponer 'Badges' que hagan visible el estado de la Quality Gate o una métrica específica, mediante el botón 'Get project badges'. Te proporciona una URL, la cual puede ser expuesta mediante un 'Badge' en un Confluence o el fichero 'README', que a su vez se publica como página en GitHub, por ejemplo.

En el siguiente post (Parte 3) trataré de forma práctica la ejecución de análisis y la inspección continua de manera automatizada de un proyecto Git (sobre npm Node o Maven) mediante Jenkins, sobre el SonarQube alojado en un contenedor de una máquina virtual Ubuntu en Azure, que se montó en la parte 1 de esta serie de post sobre SonarQube.

Si quieres estar al tanto de la tercera entrega y de otros posts, ¡síguenos en Twitter!

Javier Larios Calleja
Autor

Javier Larios Calleja

Senior QA Consultant (Presales) & QA Manager de la comunidad de 'QA & Testing' de atSistemas. + 10 años dedicados a la Calidad y actualmente centrado en proporcionar estrategias de QA/QC.