Grandes frases en inglés: Code Coverage

14
septiembre
2006

En realidad nunca he escuchado la palabra en español (de hecho creo que nunca la escuchado ni en inglés) pero supongo que code coverage se debe traducir por algo parecido a “recubrimiento” o “cobertura de código”. Por no liar las cosas (y porque, al menos a mi, me suenan fatal las traducciones) mantendré la frase en inglés para no liarnos.

El code coverage es una medida que se utiliza en las disciplinas de comprobación automática (automated testing) de software. Esta medida indica la fracción de del software que las pruebas han cubierto. Si las pruebas nos indican que nuestro software es correcto, el code coverage nos indica que partes de nuestro software son correctas (esto no es del todo cierto, como veremos más adelante). Es decir, el code coverage es una medida de calidad, pero no de calidad de nuestro software, sino de nuestras pruebas: nos indica que partes del software están comprobando nuestras pruebas y, lo más importante, cuáles partes no estamos comprobando.

El code coverage, como las pruebas automáticas y la documentación del código son “cosas que hacen perder el tiempo” a los desarrolladores tontos y “salvadores” para los desarrolladores con cabeza, aunque en realidad el code coverage no nos hace perder mucho el tiempo, ya que la mayoría de los casos es cuestión de utilizar alguna herramienta sobre nuestro software, preferentemente sobre el ejecutable que realiza nuestras pruebas (si lo probamos sobre un ejecutable final lo máximo que obtendremos es las partes del software que el usuario ha utilizado).

La medida del code coverage de nuestro software siempre será mejor cuanto más cerca del 100% esté, pero llegar a esos números o incluso cerca puede llegar a ser contraproductivo. La idea es utilizar la herramienta de code coverage sobre nuestras pruebas, comprobar que partes del código no se han ejercitado y escribir nuevas pruebas que utilicen esas partes. Un code coverage superior a 95% es un buen punto para detenerse.

Sin embargo la mayoría de herramientas de code coverage no son capaces de comprobar más que lo que se llama “cobertura de instrucción” o “de línea” (statement coverage o line coverage, a veces denominado C0), que indica si una instrucción se ha ejecutado o no. En la mayoría de los casos esta medida ya dice mucho de la calidad de las pruebas, pero no siempre: por ejemplo, el siguiente código obtendría un 100% de cobertura si se ejecutase cualquiera de las ramas:

if (condicion) { codigo 1; } else { codigo 2;}

Pero obviamente sí solo se ha ejecutado una de las ramas no se han comprobado todos los caminos posibles. Otras medidas como la “cobertura de ramas” o la “cobertura de bloques” (branch coverage o C1, y block coverage) resuelven este problema.

Más allá de C1 existen algunas medidas más de code coverage: entre las más interesantes está C2 o “cobertura de caminos” (path coverage) que se encarga de comprobar que todos los caminos posibles entre el punto de entrada de una función y el/los puntos de salida han sido cubiertos.

int funcion(bool condicion1, bool condicion2, bool condicion3)
{
    int resultado = 0;
    
    if (condicion1) resultado += 1;
    if (condicion2) resultado += 2;
    if (condicion3) resultado += 3;
    
    return resultado;
}

En el fragmento de código anterior existen 23=8 caminos posibles. Nuestras pruebas deberían comprobar cada una de esas 8 posibilidades para conseguir una cobertura C2 del 100%, mientras que con una única prueba conseguiríamos una cobertura C0 total. Es por esto que los números que nos proporcionan las herramientas para medir el code coverage no deben ser tomadas como valores absolutos, sino como indicaciones sobre como orientar nuestras siguientes pruebas.

Para realizar las medidas de code coverage existen multitud de herramientas, sobre todo para Java y .Net (los lenguajes con máquina virtual y grandes capacidades de reflexividad son más sencillos de comprobar que programas nativos, además de que últimamente son mucho más utilizados), pero se puede encontrar casi para cualquier lenguaje. Podéis ver una pequeña lista de herramientas de code coverage en el wiki de C2.

La mayoría de herramientas open source proporcionan medidas de C0 (que ya es bastante, tengo que decir) y si tenemos suerte de C1. Pocas herramientas open source proporcionan medidas de C2 o medidas más sofisticadas, aunque sí existen herramientas comerciales que dicen proporcionar tales medidas. Generalmente C0 nos da una buena idea de la calidad de nuestras pruebas y C1 nos proporciona más seguridad sobre esas medidas, con lo que la mayoría de herramientas open source nos bastarán para quitarnos un gran peso de encima.

Esta entrada tiene una razón: hace unas semanas empecé a utilizar rcov para comprobar la cobertura de mis pruebas en un proyecto con Rails (¡92% de cobertura! ¡tengo que mejorarlo!) y hoy he deseado tener una herramienta parecida pero para C++, aunque lo único que he encontrado es gcov, que depende de GCC y desde luego no proporciona resultados tan agradables como rcov.

Por cierto, a pesar de no haber encontrado una herramienta de code coverage que me guste para C++, las pruebas de unidad realizadas con CppUnit han sido mis “salvadoras” de hoy: estaba intentando que el proyecto que llevo realizando cerca de 7 meses en Windows y Visual C++ compilara en Mac OS X y Xcode (utilizando GCC 4.0 por debajo). Después de conseguir aplastar 4 o 5 problemas de compilación y un par de problemillas con el nuevo IDE, he ejecutado las pruebas y han terminado con un alegre “OK” escrito al final. En ese momento he recuperado todo el tiempo que pudiera haber “perdido” escribiendo todas las pruebas (unas 150, por ahora).

Ahora ya no necesito Windows (casi) para nada.

Enlaces interasantes


Los comentarios están cerrados.

Tu servidor sin límites: 20GB de espacio, 1TB de transferencia, 1 dominio gratuito. Por 1.5€ al mes utilizando el código "RUIDOBLANCO" en DreamHost. Más información.