¿Es la cobertura de código irrelevante?


Después de leer el artículo "Is Code Coverage Irrelevant?" by Ron Jeffries siento la necesidad de aceptar el reto y contar lo que realmente opino sobre la cobertura de código.

Desde hace algún tiempo he estado pensando en escribir este artículo... Así que creo que éste es el mejor momento.

¿Qué significa la cobertura?

Comencemos con este twit:

Dos proyectos, uno con el 95% de cobertura con tests, otro con 45%. Pagan por error encontrado. ¿En cuál quieres trabajar?

Bueno... Estoy de acuerdo con la gente que dijo que depende. No tengo suficiente información para decidir.

Pero mi primera pregunta es diferente de la de otra gente: ¿Qué tipo de cobertura?

A menudo las empresas medien la cobertura sin pensar en ello, pero la cobertura dada por los diferentes tests significa diferentes cosas.

La cobertura de los tests unitarios puede indicar la intención de pruebas. Una cobertura alta producida por los tests unitarios significa que se ha tratado de probar concienzudamente, a pesar de que no es garantía de que se haya logrado.

Es difícil incrementar la cobertura de los tests unitarios. De hecho, es muy difícil tener tests unitarios realmente buenos.

Por otra parte, la cobertura de los tests de integración nos muestra la cantidad de código que no se ha probado de ninguna manera. Es decir: no es una medida de la bondad, sino de la duda. Se puede asegurar que el código probado funciona al menos para un caso de uso, pero el código no probado... Es un misterio. He tenido código python fallando en métodos triviales por una errata, sólo porque no había ningún test.

Y, finalmente, la cobertura de los tests de aceptación muestra qué métodos probablemente no se usan o no son útiles. Nadie se preocupó de probarlos, por lo que probablemente no haya un flujo para llegar hasta ellos y están obsoletos o bien están aportando una funcionalidad innecesaria.

Lamentablemente, las empresas tienden a unir todos estos porcentajes.

En general, el número que dice más es el código no cubierto, a pesar de que la gente sólo mira el código cubierto.

¿Qué ofrece en realidad una alta cobertura?

Bueno... Ofrece probabilidades.

Por ejemplo, con FormatMessage, un método de la API de Windows, es difícil conseguir una alta cobertura: demasiados argumentos, demasiados flujos. Requeriría un montón de tests. Pero las líneas no cubiertas nos muestran dónde es más probable que falle el código.

Con la típica función math.sqrt, que devuelve la raíz cuadrada de un número dado, es fácil obtener un 100% de cobertura sin probar nada en absoluto: puede fallar con un cero o valores negativos, o incluso funcionar sólo para un par de números. Por lo tanto, la cobertura nos dice... probablemente nada.

Sólo podemos hablar del código no cubierto, porque es algo desconocido.

Además, una alta cobertura en los tests unitarios puede significar que se tienen métodos muy pequeños, que desperdiciamos un montón de tiempo en las pruebas o bien que tenemos test unitarios muy malos (que realmente son tests de integración). Probablemente.

Conclusión

Me gusta muchísimo el artículo Code coverage goal: 80% and no less!, de Alberto Savoia. La cobertura es algo que nos ayuda a asegurarnos de lo que hace nuestro código y de sus puntos débiles. No se puede utilizar como una medida de avance o la bondad de los desarrolladores.

Como siempre digo: Es sencillo conseguir un 100% de cobertura, pero lo difícil es probarlo todo.


Comentarios

Comments powered by Disqus