¿Cuánta cobertura de código es "suficiente"?

37

Estamos comenzando a presionar por la cobertura del código aquí en mi trabajo, y me ha hecho pensar ... ¿Cuánta cobertura del código es suficiente?

¿Cuándo llega al punto de disminuir la rentabilidad de la cobertura del código? ¿Cuál es el punto óptimo entre una buena cobertura y la insuficiente? ¿Varía según el tipo de proyecto que está haciendo (es decir, WPF, WCF, Mobile, ASP.NET) (Estas son las clases de C # que estamos escribiendo).

Vaccano
fuente
Realmente no hay una buena respuesta a esto; " ¿Cuánta cobertura de prueba de unidad necesita? " En los foros de desarrolladores de Artima tiene algunos consejos útiles.
RN01

Respuestas:

19

Apuntamos al menos al 70%. En cosas que son más fácilmente comprobables (estructuras de datos funcionales, por ejemplo), apuntamos al 90% y la mayoría de las personas apuntan al 100% lo más posible. En cosas relacionadas con WPF y otros marcos que son muy difíciles de probar, obtenemos una cobertura mucho menor (apenas 70%).

Noah Richards
fuente
¿Es WPF inherentemente difícil de probar o todavía no ha gastado el esfuerzo en elaborar la mejor estrategia para obtener una mejor cobertura?
JBRWilkinson
Mucho de esto se debe al hecho de que la entrada de WPF es difícil de falsificar. Nuestras pruebas son tan unitarias y API como podemos obtener, y la imposibilidad de falsificar fácilmente la capa que se encuentra "encima" de WPF (entrada, al menos) dificulta la prueba. No es un gran problema, ya que las partes de la API que no son GUI son fáciles de probar, pero es el último tramo que va de nuestro modelo (o modelo de vista) a WPF lo que es desafiante.
Noah Richards
1
Sí, WPF es una perra para probar. Y podría vivir con eso si hubiera tiempo de compilación comprobando los enlaces en las vistas. Entonces, al menos, la compilación se rompería si cambia una propiedad a la que se vincula la vista. Pero no lo hace. Eso nos ha llevado a utilizar la automatización de la GUI en nuestras pruebas de aceptación, que también es una tarea difícil de escribir. Pero al menos nos da confianza de que el sistema funciona.
Pete
Me gusta el número (70%). A medida que mis equipos crecen, tiendo a comenzar a buscar pruebas de cobertura que de valor. En el comentario de WPF, estamos en los primeros días. Es decir, no estamos construyendo / estructurando código WPF para que sea fácilmente comprobable. Los modelos simulados ayudan. Al diseñar el código, diséñalo para que sea comprobable. Y sí, en este punto hay ejemplos limitados, por lo que tendrá que pensarlo. No es diferente de donde estaban la mayoría de los desarrolladores, ya que TDD se les presentó por primera vez con menos experiencia en la industria.
Jim Rush
para ser más específico, WPF es una prueba de prueba de unidad a unidad , si necesita una mayor cobertura por alguna razón, la forma más fácil de aumentar la cobertura de las clases de WPF es con pruebas de UI codificadas / pruebas de integración
jk.
55

Soy de la opinión de que la cobertura de código por sí sola es una métrica pobre. Es fácil producir toneladas de pruebas inútiles que cubren el código, pero no verifica adecuadamente la salida, o no prueba casos extremos, por ejemplo. El código de cobertura solo significa que no arroja una excepción, no es que sea correcto. Necesita pruebas de calidad, la cantidad no es tan importante.

Fishtoaster
fuente
8
La cobertura de código debe ser uno de los resultados de sus pruebas automatizadas que se realizan en su sistema de compilación automatizado. No vale la pena realizar pruebas que no comprueben la salida. La cobertura por debajo del umbral indica nuevas funciones sin pruebas / pruebas insuficientes. No debería ser algo con lo que golpear a la gente, pero ciertamente puede marcar un código no probado.
JBRWilkinson
3
Segundo JBRWilkinson aquí, aunque no es un indicador de buen código, la cobertura del código puede ser un indicador de falta de pruebas. Por cierto, las pruebas unitarias también pueden ofrecer otras métricas, como medidas de rendimiento, para que no se sorprenda repentinamente cuando una nueva versión se derrumba en el servidor bajo la carga de trabajo inesperada.
Matthieu M.
44
Creo que esta es una elección falsa. Las pruebas de alta calidad que solo tocan una pequeña cantidad de código son medidas generales de calidad deficientes, al igual que las "pruebas" que tocan una gran cantidad de código pero realmente no verifican los resultados. Dicho de otra manera, imagine un proceso de garantía de calidad para automóviles que fue muy exhaustivo al probar la rueda del lado del conductor delantero, pero no en otra parte del automóvil. Eso sería malo de la misma manera que un proceso de control de calidad que era solo un tipo que miraba todo el auto y decía "sí, se ve bien".
Noah Richards
38

"Suficiente" es cuando puede hacer cambios a su código con la confianza de que no está rompiendo nada. En algunos proyectos, podría ser del 10%, en otros, podría ser del 95%.

Casi nunca es tan alto como el 100%. Sin embargo, a veces tratar de obtener una cobertura del código del 100% puede ser una excelente manera de eliminar el cruft de la base del código. No olvide que hay dos formas de aumentar la cobertura del código: escriba más pruebas o elimine el código. Si el código no está cubierto porque es difícil de probar, existe una buena posibilidad de que pueda simplificar o refactorizar para facilitar la prueba. Si es demasiado oscuro para molestarse en probar, generalmente hay una buena posibilidad de que nada más en el código lo esté usando.

RevBingo
fuente
24
"Prueba hasta que el miedo se convierta en aburrimiento"
Brad Mace
2
Vota por el comentario sobre la eliminación del código. Utilizo métricas de cobertura de código para eso todo el tiempo (en VS, donde resalta las líneas que no están cubiertas).
Noah Richards
Great quote @bemace
jayraynet
14

La cobertura del código se aproxima al 100% asintóticamente. En consecuencia, ese último 5% es probablemente más esfuerzo de lo que vale, ya que comienza a obtener rendimientos muy pequeños por el esfuerzo realizado.

Robert Harvey
fuente
7

La cobertura es una medida a tener en cuenta, pero no debería ser el objetivo final. He visto (¡y ciertamente lo he escrito!) Un montón de código de alta cobertura: 100% de cobertura (TDD, por supuesto), pero:

  • los errores siguen apareciendo
  • el diseño aún puede ser pobre
  • realmente puedes matarte disparando para algún objetivo de cobertura arbitrario: elige tus batallas: p

Hay un "Camino de Testivus" de entrada que creo que es apropiado para hacer referencia aquí :)

HY
fuente
5

Solo el 20% de la mayoría del código se ejecutará el 80% del tiempo . Un análisis de cobertura de código no es muy útil a menos que se combine con un gráfico de llamadas para determinar qué necesita probarse más. Eso te dice dónde es probable que estén tus casos límite. Puede llegar a 100 pruebas solo para esos casos límite, que constituyen menos del 5% del código real.

Por lo tanto, asegúrese de cubrir el 100% del 20% que define las rutas críticas, y al menos el 50% del resto (según el gráfico de llamadas). Esto debería brindarle (aproximadamente) un 70% - 75% de cobertura total, pero varía.

No pierda tiempo intentando obtener más del 70% de cobertura total mientras deja casos críticos críticos sin controles.

Tim Post
fuente
¿Las herramientas de Cobertura de Código no generan un Gráfico de Llamadas por definición?
JBRWilkinson
4

Use la cobertura como guía para indicar áreas no probadas. En lugar de tener un mandato para la cobertura, es más sabio comprender el motivo del código no cubierto. Registrar una razón del déficit es una buena disciplina que permite equilibrar los riesgos.

A veces, la razón es menos deseable "por ejemplo, se acabó el tiempo", pero podría estar bien para un lanzamiento temprano. Es mejor marcar las áreas a las que volver para obtener un aumento en la cobertura más adelante.

Trabajo en software de vuelo crítico donde el 100% de cobertura de estado de cuenta se considera adecuado para sistemas no críticos. Para los sistemas más críticos, verificamos la cobertura de rama / decisión y usamos una técnica llamada MC / DC que a veces no es lo suficientemente estricta.

También tenemos que asegurarnos de que también hemos cubierto el código objeto.

Es un equilibrio entre riesgo, en nuestro caso muy alto, contra valor / costo. Se necesita una elección informada basada en el riesgo de perder un error.

Mark Fisher
fuente
3

Cuando comience a considerar los cambios que afectarían el rendimiento del tiempo de ejecución, la seguridad, la flexibilidad o la facilidad de mantenimiento para permitir una mayor cobertura de código, es hora de finalizar la búsqueda de más cobertura de código.

Tengo proyectos en los que ese punto es del 0% porque la cobertura es imposible de calcular sin dañar el diseño y otros proyectos en los que eso es tan alto como el 92%.

Las métricas de cobertura de código solo son útiles para señalar si podría haberse perdido algunas pruebas. No le dicen nada sobre la calidad de sus pruebas.

Cuenta
fuente
2

El software de espacio crítico requiere una cobertura del estado de cuenta del 100%.

Al principio no tiene sentido. Todo el mundo sabe que una cobertura de prueba completa no significa que el código se haya probado completamente y que no es tan difícil obtener una cobertura del 100% sin probar realmente la aplicación.

Sin embargo, el 100% de cobertura es un límite inferior: aunque el 100% de cobertura no es una prueba de un software libre de errores, es cierto que con una cobertura menor, el código no se prueba completamente y esto es simplemente inaceptable para el software de espacio crítico.

Mouviciel
fuente
2

Realmente me gusta la respuesta de @ RevBingo porque sugiere que la lucha hacia el 100% puede hacer que limpies o elimines el código no utilizado. Lo que no he visto en las otras respuestas es una idea de cuándo necesita una alta cobertura y cuándo no. Intenté comenzar esto. Creo que agregar detalles a un cuadro como este sería una búsqueda más útil que encontrar un número de cobertura de prueba que fuera adecuado para todo el código.

100%

Para una API pública, como las Colecciones java.util, que no está acoplada a una Base de Datos y no devuelve HTML, creo que el 100% de cobertura es un objetivo inicial noble, incluso si se conforma con el 90-95% debido al tiempo u otro restricciones El aumento de la cobertura de la prueba después de completar la función obliga a un nivel de escrutinio más detallado que otros tipos de revisión de código. Si su API es popular, la gente la usará, la subclasificará, la deserializará, etc. de maneras que no puede esperar. ¡No quieres que su primera experiencia sea encontrar un error o supervisar el diseño!

90%

Para el código de infraestructura empresarial, que toma estructuras de datos y devuelve estructuras de datos, el 100% sigue siendo probablemente un buen objetivo inicial, pero si este código no es lo suficientemente público como para invitar a un mal uso, ¿quizás el 85% sigue siendo aceptable?

75%

Para el código que acepta y devuelve cadenas, creo que las pruebas unitarias son mucho más frágiles, pero aún pueden ser útiles en muchas situaciones.

50% o menos

Odio escribir pruebas para funciones que devuelven HTML porque es muy frágil. ¿Qué sucede si alguien cambia el CSS, el JavaScript o todo el blob de HTML e inglés que devuelve no tiene sentido para los usuarios finales humanos? Si puede encontrar una función que use mucha lógica de negocios para producir un poco de HTML, vale la pena probarlo. Pero puede que no valga la pena probar la situación inversa.

Cerca del 0%

Para algunos códigos, la definición de "correcto" es "tiene sentido para el usuario final". Hay pruebas no tradicionales que puede realizar con este código, como la verificación gramatical automática o la validación HTML de la salida. Incluso he configurado declaraciones grep para pequeñas inconsistencias de las que comúnmente somos víctimas en el trabajo, como decir "Iniciar sesión" cuando el resto del sistema lo llama "Iniciar sesión". Este hombre no es estrictamente una prueba unitaria, sino una forma útil de detectar problemas sin esperar resultados específicos.

Sin embargo, en última instancia, solo un humano puede juzgar qué es sensible para los humanos. Las pruebas unitarias no pueden ayudarte allí. A veces se necesitan varios humanos para juzgar eso con precisión.

Absoluto 0%

Esta es una categoría triste y me siento menos persona por escribirla. Pero en cualquier proyecto suficientemente grande hay agujeros de conejos que pueden succionar a la persona por semanas sin proporcionar ningún beneficio comercial.

Compré un libro porque decía que mostraba cómo burlarse automáticamente de los datos para probar Hibernate. Pero solo probó las consultas Hibernate HQL y SQL. Si tiene que hacer mucho HQL y SQL, realmente no está obteniendo la ventaja de Hibernate. Hay una forma de base de datos en memoria Hibernate, pero no he invertido el tiempo para descubrir cómo usarla de manera efectiva en las pruebas. Si tuviera eso en ejecución, me gustaría tener una cobertura de prueba alta (50% -100%) para cualquier lógica de negocios que calcule cosas navegando por un gráfico de objetos que hace que Hibernate ejecute algunas consultas. Mi capacidad para probar este código está cerca del 0% en este momento y eso es un problema. Así que mejoro la cobertura de pruebas en otras áreas del proyecto y trato de preferir funciones puras sobre las que acceden a la base de datos, en gran parte porque es más fácil escribir pruebas para esas funciones. Todavía,

GlenPeterson
fuente
1

Creo que depende de la parte de la aplicación que esté probando. Por ejemplo, para la lógica de negocios o cualquier componente que implique transformaciones de datos complejas, apuntaría a una cobertura del 90% (lo más alta posible). A menudo he encontrado errores pequeños pero peligrosos simplemente probando la mayor cantidad de código posible. Prefiero encontrar esos errores durante las pruebas que dejar que ocurran en el sitio de un cliente un año después. Además, un beneficio de una alta cobertura de código es que evita que las personas cambien el código de trabajo con demasiada facilidad, ya que las pruebas tienen que adaptarse de manera correspondiente.

Por otro lado, creo que hay componentes para los que la cobertura de código es menos adecuada. Por ejemplo, cuando se prueba una GUI, lleva mucho tiempo escribir una prueba que cubra todo el código que se ejecuta al hacer clic en un botón para enviar el evento a los componentes correctos. Creo que en este caso es mucho más efectivo usar el enfoque tradicional de realizar una prueba manual en la que simplemente haga clic en el botón y observe el comportamiento del programa (¿se abre la ventana de diálogo correcta? ¿Se selecciona la herramienta correcta? ?)

Giorgio
fuente
0

No tengo esa gran opinión sobre el uso de la cobertura de código como una medida para saber cuándo su conjunto de pruebas tiene suficiente cobertura.

La razón principal es porque si tiene un proceso en el que primero escribe un código, luego algunas pruebas, y luego mira la cobertura del código para descubrir dónde se perdió una prueba, entonces es su proceso el que necesita mejorar. Si haces TDD verdadero, entonces tienes una cobertura de código 100% lista para usar (es cierto, hay algunas trivialidades que no pruebo). Pero si observa la cobertura del código para averiguar qué probar, probablemente escriba las pruebas incorrectas.

Entonces, lo único que puede concluir de la cobertura del código es que si es demasiado bajo, no tiene suficientes pruebas. Pero si es alto, no hay garantía de que tenga todas las pruebas correctas.

Pete
fuente