Si tuviera que exigir un porcentaje mínimo de cobertura de código para las pruebas unitarias, tal vez incluso como un requisito para comprometerse con un repositorio, ¿cuál sería?
Por favor explique cómo llegó a su respuesta (ya que si todo lo que hizo fue elegir un número, entonces podría haberlo hecho yo solo;)
unit-testing
code-coverage
code-metrics
cordura
fuente
fuente
Respuestas:
Esta prosa de Alberto Savoia responde precisamente esa pregunta (¡de una manera muy entretenida!):
http://www.artima.com/forums/flat.jsp?forum=106&thread=204677
fuente
La cobertura de código es una métrica engañosa si su objetivo es obtener una cobertura del 100% (en lugar de probar el 100% de todas las funciones).
Así que confía en ti mismo o en tus desarrolladores para ser minucioso y cubrir cada ruta a través de su código. Sé pragmático y no persigas la mágica cobertura del 100%. Si TDD su código, debería obtener una cobertura de más del 90% como bonificación. Use la cobertura de código para resaltar fragmentos de código que se ha perdido (aunque no debería suceder si TDD ... ya que escribe el código solo para pasar una prueba. Ningún código puede existir sin su prueba asociada).
fuente
La cobertura de código es excelente, pero la cobertura de funcionalidad es aún mejor. No creo en cubrir cada línea que escribo. Pero sí creo en escribir una cobertura de prueba del 100% de toda la funcionalidad que quiero proporcionar (incluso para las características extra interesantes que vine conmigo y que no se discutieron durante las reuniones).
No me importa si tendría un código que no está cubierto en las pruebas, pero me importaría si refactorizara mi código y terminara teniendo un comportamiento diferente. Por lo tanto, el 100% de cobertura funcional es mi único objetivo.
fuente
La respuesta aceptada hace un buen punto: no hay un solo número que tenga sentido como estándar para cada proyecto. Hay proyectos que simplemente no necesitan ese estándar. Cuando la respuesta aceptada se queda corta, en mi opinión, es en describir cómo se puede tomar esa decisión para un proyecto dado.
Intentaré hacerlo. No soy un experto en ingeniería de pruebas y me complacería ver una respuesta más informada.
Cuándo establecer los requisitos de cobertura del código
Primero, ¿por qué querrías imponer tal estándar en primer lugar? En general, cuando desea introducir confianza empírica en su proceso. ¿Qué quiero decir con "confianza empírica"? Bueno, la verdadera corrección del objetivo . Para la mayoría del software, no podemos saber esto en todas las entradas, por lo que nos conformamos con decir que el código está bien probado . Esto es más conocido, pero sigue siendo un estándar subjetivo: siempre estará abierto a debatir si lo has cumplido o no. Esos debates son útiles y deberían ocurrir, pero también exponen incertidumbre.
La cobertura del código es una medida objetiva: una vez que vea su informe de cobertura, no hay ambigüedad sobre si los estándares cumplidos son útiles. ¿Prueba lo correcto? En absoluto, pero tiene una relación clara con lo bien probado que está el código, que a su vez es nuestra mejor manera de aumentar la confianza en su corrección. La cobertura del código es una aproximación medible de cualidades inconmensurables que nos interesan.
Algunos casos específicos en los que tener un estándar empírico podría agregar valor:
Qué métricas usar
La cobertura del código no es una sola métrica; Hay varias formas diferentes de medir la cobertura. El criterio sobre el que puede establecer un estándar depende de lo que esté usando para satisfacerlo.
Usaré dos métricas comunes como ejemplos de cuándo podría usarlas para establecer estándares:
if
), ¿se han evaluado ambas ramas? Esto da una mejor idea de la cobertura lógica de su código: ¿Cuántas de las posibles rutas que puede tomar mi código he probado?Hay muchas otras métricas (la cobertura de línea es similar a la cobertura de declaración, pero produce diferentes resultados numéricos para declaraciones de varias líneas, por ejemplo; la cobertura condicional y la cobertura de ruta es similar a la cobertura de rama, pero reflejan una vista más detallada de las posibles permutaciones de ejecución del programa que pueda encontrar).
Qué porcentaje requerir
Finalmente, volviendo a la pregunta original: si establece estándares de cobertura de código, ¿cuál debería ser ese número?
Esperemos que esté claro en este punto que estamos hablando de una aproximación para comenzar, por lo que cualquier número que elijamos será inherentemente aproximado.
Algunos números que uno podría elegir:
No he visto números por debajo del 80% en la práctica, y me cuesta imaginar un caso en el que uno los establezca. El papel de estos estándares es aumentar la confianza en la corrección, y los números por debajo del 80% no son particularmente inspiradores de confianza. (Sí, esto es subjetivo, pero de nuevo, la idea es hacer la elección subjetiva una vez que establezca el estándar y luego usar una medición objetiva en el futuro).
Otras notas
Lo anterior supone que el objetivo es la corrección. La cobertura del código es solo información; Puede ser relevante para otros objetivos. Por ejemplo, si le preocupa la capacidad de mantenimiento, probablemente le interese el acoplamiento suelto, que puede demostrarse mediante la capacidad de prueba, que a su vez se puede medir (en ciertas modas) mediante la cobertura del código. Por lo tanto, su estándar de cobertura de código proporciona una base empírica para aproximar también la calidad de la "mantenibilidad".
fuente
La cobertura de mi código favorito es 100% con un asterisco. El asterisco aparece porque prefiero usar herramientas que me permitan marcar ciertas líneas como líneas que "no cuentan". Si he cubierto el 100% de las líneas que "cuentan", ya he terminado.
El proceso subyacente es:
De esta manera, si yo y mis colaboradores agregamos un nuevo código o cambiamos las pruebas en el futuro, hay una línea brillante que nos dice si nos perdimos algo importante: la cobertura cayó por debajo del 100%. Sin embargo, también proporciona la flexibilidad para lidiar con diferentes prioridades de prueba.
fuente
// @codeCoverageIgnore
y se excluirá de la cobertura.Me gustaría compartir otro anectodo sobre la cobertura de prueba.
Tenemos un gran proyecto en el que, en Twitter, noté que, con 700 pruebas unitarias, solo tenemos un 20% de cobertura de código .
Scott Hanselman respondió con palabras de sabiduría :
Nuevamente, se remonta a mi Testivus en la respuesta de cobertura de código . ¿Cuánto arroz debes poner en la olla? Depende.
fuente
Para un sistema bien diseñado, donde las pruebas unitarias han impulsado el desarrollo desde el principio, diría que el 85% es un número bastante bajo. Las clases pequeñas diseñadas para ser comprobables no deberían ser difíciles de cubrir mejor que eso.
Es fácil descartar esta pregunta con algo como:
Es cierto, pero hay algunos puntos importantes que hacer sobre la cobertura del código. En mi experiencia, esta métrica es bastante útil cuando se usa correctamente. Dicho esto, no he visto todos los sistemas y estoy seguro de que hay toneladas de ellos en los que es difícil ver el análisis de cobertura de código que agrega algún valor real. El código puede verse muy diferente y el alcance del marco de prueba disponible puede variar.
Además, mi razonamiento se refiere principalmente a bucles de retroalimentación de prueba bastante cortos. Para el producto que estoy desarrollando, el ciclo de retroalimentación más corto es bastante flexible y abarca desde pruebas de clase hasta señalización entre procesos. Por lo general, probar un subproducto entregable lleva 5 minutos y, para un ciclo de retroalimentación tan corto, de hecho es posible usar los resultados de la prueba (y específicamente la métrica de cobertura de código que estamos viendo aquí) para rechazar o aceptar confirmaciones en el repositorio.
Al usar la métrica de cobertura del código, no solo debe tener un porcentaje fijo (arbitrario) que debe cumplirse. Hacer esto no le brinda los beneficios reales del análisis de cobertura de código en mi opinión. En su lugar, defina las siguientes métricas:
El nuevo código solo se puede agregar si no vamos por encima del LWM y no vamos por debajo del HWM. En otras palabras, no se permite que disminuya la cobertura del código , y se debe cubrir el nuevo código. Observe cómo digo debería y no debe (explicado a continuación).
Pero, ¿no significa esto que será imposible limpiar la basura vieja y bien probada para la que ya no tiene uso? Sí, y es por eso que debes ser pragmático sobre estas cosas. Hay situaciones en las que las reglas tienen que romperse, pero para su integración diaria típica, mi experiencia es que estas métricas son bastante útiles. Dan las siguientes dos implicaciones.
Se promueve el código comprobable. Al agregar un nuevo código, realmente debe hacer un esfuerzo para que el código sea comprobable, ya que tendrá que intentar cubrirlo todo con sus casos de prueba. El código comprobable suele ser algo bueno.
La cobertura de prueba para el código heredado aumenta con el tiempo. Al agregar un nuevo código y no poder cubrirlo con un caso de prueba, se puede tratar de cubrir algún código heredado para evitar la regla LWM. Esta trampa a veces necesaria al menos da el efecto secundario positivo de que la cobertura del código heredado aumentará con el tiempo, haciendo que la aplicación aparentemente estricta de estas reglas sea bastante pragmática en la práctica.
Y de nuevo, si el ciclo de retroalimentación es demasiado largo, puede ser completamente poco práctico configurar algo como esto en el proceso de integración.
También me gustaría mencionar dos beneficios generales más de la métrica de cobertura del código.
El análisis de cobertura de código es parte del análisis de código dinámico (en oposición al análisis estático, es decir, Lint). Los problemas encontrados durante el análisis de código dinámico (por herramientas como la familia purify, http://www-03.ibm.com/software/products/en/rational-purify-family ) son cosas como lecturas de memoria no inicializadas (UMR), pérdidas de memoria, etc. Estos problemas solo se pueden encontrar si el código está cubierto por un caso de prueba ejecutado . El código que es más difícil de cubrir en un caso de prueba suele ser los casos anormales en el sistema, pero si desea que el sistema falle correctamente (es decir, el seguimiento de errores en lugar de bloquearse) es posible que desee esforzarse para cubrir los casos anormales en el análisis de código dinámico también. Con solo un poco de mala suerte, un UMR puede conducir a una falla por defecto o peor.
Las personas se enorgullecen de mantener el 100% para el nuevo código, y discuten los problemas de prueba con una pasión similar a otros problemas de implementación. ¿Cómo se puede escribir esta función de una manera más comprobable? ¿Cómo tratarías de cubrir este caso anormal, etc.
Y una negativa, para completar.
fuente
Si este fuera un mundo perfecto, el 100% del código estaría cubierto por pruebas unitarias. Sin embargo, dado que este NO es un mundo perfecto, es una cuestión de para qué tienes tiempo. Como resultado, recomiendo centrarse menos en un porcentaje específico y centrarse más en las áreas críticas. Si su código está bien escrito (o al menos un facsímil razonable del mismo) debe haber varios puntos clave donde las API están expuestas a otro código.
Concentre sus esfuerzos de prueba en estas API. Asegúrese de que las API estén 1) bien documentadas y 2) tengan escritos los casos de prueba que coincidan con la documentación. Si los resultados esperados no coinciden con los documentos, entonces tiene un error en su código, documentación o casos de prueba. Todos los cuales son buenos para examinar.
¡Buena suerte!
fuente
Muchas tiendas no valoran las pruebas, por lo que si está por encima de cero, al menos, hay una apreciación del valor, por lo que podría decirse que no es cero, ya que muchas siguen siendo cero.
En el mundo .Net, la gente suele citar el 80% como razonable. Pero dicen esto a nivel de solución. Prefiero medir a nivel de proyecto: el 30% podría estar bien para el proyecto de interfaz de usuario si tiene Selenium, etc. o pruebas manuales, el 20% para el proyecto de capa de datos podría estar bien, pero el 95% o más podría ser bastante alcanzable para el negocio capa de reglas, si no es totalmente necesaria. Por lo tanto, la cobertura general puede ser, digamos, del 60%, pero la lógica comercial crítica puede ser mucho mayor.
También he escuchado esto: aspira al 100% y llegarás al 80%; pero aspira al 80% y alcanzarás el 40%.
En pocas palabras: aplique la regla 80:20 y deje que el recuento de errores de su aplicación lo guíe.
fuente
La cobertura del código es solo otra métrica. En sí mismo, puede ser muy engañoso (ver www.thoughtworks.com/insights/blog/are-test-coverage-metrics-overrated ). Por lo tanto, su objetivo no debe ser lograr una cobertura de código del 100%, sino garantizar que pruebe todos los escenarios relevantes de su aplicación.
fuente
El 85% sería un buen punto de partida para los criterios de registro.
Probablemente elegí una variedad de barras más altas para los criterios de envío, dependiendo de la importancia de los subsistemas / componentes que se prueban.
fuente
Utilizo cobertura, y sea cual sea el porcentaje, recomendaría mantener actualizados los valores de la tarea de verificación de cobertura. Como mínimo, siga aumentando la alineación total y la ramificación total por debajo de su cobertura actual, pero nunca baje esos valores. También vincule la propiedad de falla de compilación Ant a esta tarea. Si la compilación falla por falta de cobertura, conoce el código agregado de alguien pero no lo ha probado. Ejemplo:
fuente
Cuando creo que mi código no se ha probado lo suficiente en la unidad y no estoy seguro de qué probar a continuación, utilizo la cobertura para ayudarme a decidir qué probar a continuación.
Si aumento la cobertura en una prueba unitaria, sé que esta prueba unitaria vale algo.
Esto va para el código que no está cubierto, 50% cubierto o 97% cubierto.
fuente
Prefiero hacer BDD, que utiliza una combinación de pruebas de aceptación automatizadas, posiblemente otras pruebas de integración y pruebas unitarias. La pregunta para mí es cuál debería ser la cobertura objetivo del conjunto de pruebas automatizadas en su conjunto.
Aparte de eso, la respuesta depende de su metodología, idioma y herramientas de prueba y cobertura. Al hacer TDD en Ruby o Python no es difícil mantener una cobertura del 100%, y vale la pena hacerlo. Es mucho más fácil administrar una cobertura del 100% que una cobertura del 90%.Es decir, es mucho más fácil llenar los vacíos de cobertura a medida que aparecen (y cuando se hacen brechas de cobertura de TDD son raros y generalmente valen la pena) que administrar una lista de vacíos de cobertura a los que no ha llegado y perder la cobertura regresiones debido a su fondo constante de código descubierto.
La respuesta también depende de la historia de su proyecto. Solo he encontrado que lo anterior es práctico en proyectos gestionados de esa manera desde el principio. He mejorado enormemente la cobertura de grandes proyectos heredados, y valió la pena hacerlo, pero nunca me pareció práctico volver y llenar cada vacío de cobertura, porque el código antiguo no probado no se entiende lo suficiente como para hacerlo correctamente y con rapidez.
fuente
Si ha estado haciendo pruebas unitarias durante un período de tiempo decente, no veo ninguna razón para que no se acerque al 95% o más. Sin embargo, como mínimo, siempre he trabajado con el 80%, incluso cuando soy nuevo en las pruebas.
Este número solo debe incluir el código escrito en el proyecto (excluye marcos, complementos, etc.) e incluso puede excluir ciertas clases compuestas completamente de código escrito de llamadas a código externo. Este tipo de llamada debe ser burlada / apagada.
fuente
En términos generales, de los varios documentos de mejores prácticas de excelencia en ingeniería que he leído, el 80% para el nuevo código en las pruebas unitarias es el punto que produce el mejor rendimiento. Superar ese CC% produce una menor cantidad de defectos por la cantidad de esfuerzo ejercido. Esta es una práctica recomendada que utilizan muchas grandes corporaciones.
Desafortunadamente, la mayoría de estos resultados son internos de las empresas, por lo que no hay literatura pública a la que pueda señalarle.
fuente
La cobertura del código es excelente, pero solo mientras los beneficios que obtenga superen el costo / esfuerzo de lograrlo.
Hemos estado trabajando con un estándar del 80% durante algún tiempo, sin embargo, acabamos de tomar la decisión de abandonar esto y, en cambio, centrarnos más en nuestras pruebas. Concentrándose en la compleja lógica de negocios, etc.
Esta decisión se tomó debido a la creciente cantidad de tiempo que pasamos persiguiendo la cobertura del código y manteniendo las pruebas unitarias existentes. Sentimos que habíamos llegado al punto en que el beneficio que estábamos obteniendo de nuestra cobertura de código se consideraba menor que el esfuerzo que tuvimos que hacer para lograrlo.
fuente
Respuesta corta: 60-80%
Respuesta larga: creo que depende totalmente de la naturaleza de su proyecto. Normalmente comienzo un proyecto por unidad probando cada pieza práctica. En el primer "lanzamiento" del proyecto, debería tener un porcentaje base bastante bueno basado en el tipo de programación que está realizando. En ese punto, puede comenzar a "aplicar" una cobertura mínima de código.
fuente
Echa un vistazo a Crap4j . Es un enfoque un poco más sofisticado que la cobertura de código directo. Combina medidas de cobertura de código con medidas de complejidad, y luego le muestra qué código complejo no se prueba actualmente.
fuente
Mi respuesta a este enigma es tener una cobertura de línea del 100% del código que puede probar y una cobertura de línea del 0% del código que no puede probar.
Mi práctica actual en Python es dividir mis módulos .py en dos carpetas: app1 / y app2 / y al ejecutar pruebas unitarias calcule la cobertura de esas dos carpetas y verifique visualmente ( debo automatizar esto algún día) que app1 tiene una cobertura del 100% y app2 tiene 0% de cobertura.
Cuando / si encuentro que estos números difieren del estándar que investigo y alteran el diseño del código para que la cobertura se ajuste al estándar.
Esto significa que puedo recomendar lograr una cobertura de línea del 100% del código de la biblioteca.
También ocasionalmente reviso la aplicación2 / para ver si puedo probar algún código allí, y si puedo moverlo a la aplicación1 /
Ahora no estoy demasiado preocupado por la cobertura agregada porque puede variar enormemente dependiendo del tamaño del proyecto, pero en general he visto del 70% a más del 90%.
Con Python, debería ser capaz de diseñar una prueba de humo que pueda ejecutar automáticamente mi aplicación mientras se mide la cobertura y, con suerte, obtener un agregado del 100% al combinar la prueba de humo con las cifras de prueba de unidad.
fuente
Ver la cobertura desde otra perspectiva: el código bien escrito con un flujo claro de control es el más fácil de cubrir, el más fácil de leer y, por lo general, el código con menos errores. Al escribir código con claridad y capacidad de cobertura en mente, y al escribir las pruebas unitarias en paralelo con el código, obtendrá los mejores resultados en mi humilde opinión.
fuente
En mi opinión, la respuesta es "depende de cuánto tiempo tengas". Trato de alcanzar el 100%, pero no hago un escándalo si no lo consigo con el tiempo que tengo.
Cuando escribo pruebas unitarias, uso un sombrero diferente en comparación con el que uso cuando desarrollo el código de producción. Pienso en lo que dice hacer el código probado y cuáles son las situaciones que pueden romperlo.
Normalmente sigo los siguientes criterios o reglas:
Que la Prueba de Unidad debe ser una forma de documentación sobre cuál es el comportamiento esperado de mis códigos, es decir. la salida esperada dada una cierta entrada y las excepciones que puede arrojar que los clientes pueden querer atrapar (¿Qué deben saber los usuarios de mi código?)
Que la Prueba de Unidad debería ayudarme a descubrir las condiciones que tal vez aún no haya pensado. (¿Cómo hacer que mi código sea estable y robusto?)
Si estas dos reglas no producen una cobertura del 100%, que así sea. Pero una vez, tengo tiempo, analizo los bloques y líneas descubiertos y determino si todavía hay casos de prueba sin pruebas unitarias o si el código necesita ser refactorizado para eliminar los códigos innecesarios.
fuente
Depende mucho de su aplicación. Por ejemplo, algunas aplicaciones consisten principalmente en código GUI que no se puede probar en la unidad.
fuente
No creo que pueda haber una regla B / W.
El código debe revisarse, con especial atención a los detalles críticos.
Sin embargo, si no se ha probado, ¡tiene un error!
fuente
Dependiendo de la criticidad del código, cualquier parte del 75% al 85% es una buena regla general. El código de envío definitivamente debe probarse más a fondo que en los servicios públicos, etc.
fuente
Esto tiene que depender de en qué fase del ciclo de vida de desarrollo de aplicaciones se encuentre.
Si ha estado en desarrollo durante un tiempo y ya tiene un montón de código implementado y ahora se está dando cuenta de que necesita pensar en la cobertura del código, entonces debe verificar su cobertura actual (si existe) y luego usar esa línea de base para establecer hitos cada sprint (o un aumento promedio durante un período de sprints), lo que significa asumir la deuda del código mientras continúa entregando valor al usuario final (al menos en mi experiencia, al usuario final no le importa un poco si ha aumentado la prueba cobertura si no ven nuevas funciones).
Dependiendo de su dominio, no es irrazonable disparar al 95%, pero debo decir que, en promedio, verá un caso promedio de 85% a 90%.
fuente
Creo que el mejor síntoma de la cobertura correcta del código es que la cantidad de problemas concretos que las pruebas unitarias ayudan a solucionar corresponde razonablemente al tamaño del código de pruebas unitarias que creó.
fuente
Creo que lo más importante es saber cuál es la tendencia de la cobertura a lo largo del tiempo y comprender los motivos de los cambios en la tendencia. Si ve los cambios en la tendencia como buenos o malos dependerá de su análisis de la razón.
fuente
Nos dirigíamos a> 80% hasta hace unos días, pero después de que usamos una gran cantidad de código generado, no nos importa el% de edad, sino que hacemos que el revisor atienda la cobertura requerida.
fuente
De la publicación de Testivus, creo que el contexto de respuesta debería ser el segundo programador. Dicho esto desde un punto de vista práctico, necesitamos parámetros / objetivos por los que luchar. Considero que esto se puede "probar" en un proceso ágil mediante el análisis del código que tenemos la arquitectura, la funcionalidad (historias de usuarios), y luego obtener un número. Según mi experiencia en el área de telecomunicaciones, diría que el 60% es un buen valor para verificar.
fuente