La cobertura de código no significa nada

No deja de sorprenderme cuanta gente le da una importancia excesiva al valor de la cobertura. Entiéndaseme bien, al valor absoluto de la cobertura. A la cifra en si.

¿Qué significa tener una cobertura del 75%? ¿Nos dice algo este 75%? Pues la verdad es que algo dice, pero muy poco. El motivo es sencillo, una simple cifra nos da muy poca información sobre nuestro testeo unitario. Esa cifra no nos dice cómo están distribuidos nuestros test unitarios, tampoco nos dice mucho sobre la calidad de los mismos, ni sobre su mantenibilidad, ni menos aun sobre el tiempo que tardan en pasar…

¿Qué situación os parece mejor? Una batería de test unitarios con una cobertura del 75% en todos los componentes o una batería de test con una cobertura del 95% en aquellos componentes de la arquitectura que más cambian y una cobertura media del 60% en el resto. Si yo pudiese elegir en que aplicación trabajar, elegiría esta segunda. Seguro que los test unitarios me van a resultar más útiles.

Miremos ahora otro aspecto importante del los test unitarios. Supongamos una aplicación con una cobertura del 90% por cierto, pero que a cambio de obtener esta cobertura hemos tenido que sacrificar la velocidad de ejecución de los test. ¿Es esta una buena situación? ¿Es conveniente sacrificar otros aspectos como velocidad, mantenibilidad, tiempo consumido en su escritura excesivo, etc… para conseguir mayor cobertura? ¿Es aumentar la cobertura a cualquier precio una buena decisión?. Evidentemente no. No debemos nunca olvidar que la cobertura no sirve si olvidamos qué hace a un test unitario un buen test.

La cobertura es importante, sumamente importante,  pero solo puesta en contexto. Siempre que miramos a las métricas debemos hacerlo desde un enfoque multidimensional. Mi cobertura es el X% es una afirmación que no nos dice nada, pero que oímos habitualmente. Cuando miramos al porcentaje de cobertura de nuestro código debemos hacerlo desde un enfoque crítico siempre acompañado de una mirada a otros aspectos de nuestro testeo unitario, entre otros:

  • Son los test mantenibles: Aspecto fundamental, si tu test no son fáciles de mantener, da igual lo que hagas, su cobertura se irá reduciendo con el tiempo.
  • Tienen más test la partes más importantes: Es una simple cuestión de economía, si tus recursos son limitados, y siempre lo son, debemos enfocar nuestros esfuerzos en aquellas partes en las que el testeo nos va a dar mejores resultados. Prestar más atenciones a aquellas partes de nuestra aplicación más propensas a cambios, luego aquellas de las que dependen otras, luego aquellos que son compartidos por varios proyectos, etc…
  • Cuál es la relación coste beneficio de nuestro testeo unitario: debemos valorar situaciones como ¿realmente interesa complicar el proyecto con una librería de mockeado solo para ganar cobertura marginalmente?, ¿añadir un poco más de cobertura será a costa de enlentecer significativamente nuestros test?, ¿por un puntito más de cobertura vamos a añadir nuevas dependencias a nuestros test?, etc..

Cuando la cobertura muestra toda su potencia, como en general cualquier métrica, es cuando se estudia cómo está evolucionando. La evolución de la cobertura es lo realmente importante. Ese es el aspecto clave. El problema es que casi cualquier framework de testeo unitario, por si mismo o combinado con alguna herramienta especifica, es capaz de darte informarte de cual es tu cobertura en un momento determinado, pero recoger la evolución de la cobertura es algo mucho más complejo. Para empezar necesitas como mínimo un proceso de construcción automatizado, un repositorio donde recoger la evolución de la cobertura, y un mecanismo para representarla.

Los afortunados que usamos Visual Studio y Team Foundation Server contamos con todo lo necesario para tirar del hilo y mirar nuestro testeo unitario de manera poliédrica.

Podemos ver la cobertura por modulo, namespace o clase de nuestra aplicación:

Podemos ver cómo evoluciona la cobertura en relación a los cambios en el código y el número de bugs:

Example Build Quality Indicators report

Ver si nuestras builds tienen cobertura suficiente y sobre todo si están pasando de situaciones de cobertura suficiente a menos cobertura:

Healthy and Unhealthy version of Build Success

Example Build Summary report

En conclusión ojo con pensar que un porcentaje de cobertura determinado es indicador suficiente.

Un saludo.