Si tengo un código que tiene una cobertura de prueba del 80% (todas las pruebas pasan), ¿es justo decir que es de mayor calidad que el código sin cobertura de prueba?
¿O es justo decir que es más fácil de mantener?
code-quality
test-coverage
David_001
fuente
fuente
Respuestas:
En sentido estricto, no es justo hacer ningún reclamo hasta que se establezca la calidad del conjunto de pruebas. Pasar el 100% de las pruebas no tiene sentido si la mayoría de las pruebas son triviales o repetitivas entre sí.
La pregunta es: en la historia del proyecto, ¿alguna de esas pruebas descubrió errores? El objetivo de una prueba es encontrar errores. Y si no lo hicieron, fallaron como pruebas. En lugar de mejorar la calidad del código, es posible que solo le den una falsa sensación de seguridad.
Para mejorar sus diseños de prueba, puede usar (1) técnicas de caja blanca, (2) técnicas de caja negra y (3) pruebas de mutación.
(1) Aquí hay algunas buenas técnicas de caja blanca para aplicar a sus diseños de prueba. Una prueba de caja blanca se construye teniendo en cuenta el código fuente específico. Un aspecto importante de las pruebas de caja blanca es la cobertura del código:
if
owhile
), ¿tiene una prueba que lo obliga a ser cierto y otro que lo obliga a ser falso? [Cobertura de decisión]&&
) o disyunción (usos||
), ¿cada subexpresión tiene una prueba donde es verdadero / falso? [Condición de cobertura]break
de un bucle cubierto?(2) Las técnicas de Blackbox se usan cuando los requisitos están disponibles, pero el código en sí no. Estos pueden conducir a pruebas de alta calidad:
(3) Finalmente, suponga que ya tiene muchas buenas pruebas de cobertura de caja blanca y técnicas de caja negra aplicadas. ¿Qué más puedes hacer? Es hora de probar sus pruebas . Una técnica que puede usar es la prueba de mutación.
En las pruebas de mutación, realiza una modificación en (una copia de) su programa, con la esperanza de crear un error. Una mutación podría ser:
Cree varias docenas de mutantes, en varios lugares de su programa [el programa aún tendrá que compilarse para realizar la prueba]. Si sus pruebas no encuentran estos errores, entonces necesita escribir una prueba que pueda encontrar el error en la versión mutada de su programa. Una vez que una prueba encuentra el error, has matado al mutante y puedes probar con otro.
Anexo : Olvidé mencionar este efecto: los errores tienden a agruparse . Lo que eso significa es que cuantos más errores encuentre en un módulo, mayor será la probabilidad de que encuentre más errores. Entonces, si tiene una prueba que falla (es decir, la prueba es exitosa, ya que el objetivo es encontrar errores), no solo debe corregir el error, sino que también debe escribir más pruebas para el módulo, utilizando el Técnicas anteriores.
Mientras encuentre errores a un ritmo constante, los esfuerzos de prueba deben continuar. Solo cuando haya una disminución en la tasa de nuevos errores encontrados, debe tener la confianza de que ha realizado buenos esfuerzos de prueba para esa fase de desarrollo.
fuente
Según una definición, es más fácil de mantener, ya que cualquier cambio importante es más probable que sea atrapado por las pruebas.
Sin embargo, el hecho de que el código pase las pruebas unitarias no significa que sea intrínsecamente de mayor calidad. El código aún puede estar mal formateado con comentarios irrelevantes y estructuras de datos inapropiadas, pero aún puede pasar las pruebas.
Sé qué código preferiría mantener y ampliar.
fuente
El código sin absolutamente ninguna prueba puede ser de muy alta calidad, legible, hermoso y eficiente (o basura total), así que no, no es justo decir que el código con una cobertura de prueba del 80% es de mayor calidad que el código sin cobertura de prueba.
Podría ser justo decir que el código 80% cubierto con buenas pruebas es probablemente de calidad aceptable y probablemente relativamente fácil de mantener. Pero realmente garantiza poco.
fuente
Yo lo llamaría más refactorable. La refactorización se vuelve extremadamente fácil si el código se cubre con muchas pruebas.
Sería justo llamarlo más mantenible.
fuente
Estoy de acuerdo con la parte mantenible. Michael Feathers recientemente publicó un video de una excelente charla sobre su llamado " La sinergia profunda entre la capacidad de prueba y el buen diseño " en el que discute este tema. En la charla, dice que la relación es unidireccional, es decir, el código que está bien diseñado es comprobable, pero el código comprobable no necesariamente está bien diseñado.
Vale la pena señalar que la transmisión de video no es excelente en el video, por lo que vale la pena descargarla si desea verla en su totalidad.
fuente
Me he estado haciendo esta pregunta desde hace algún tiempo en relación con la "cobertura de la condición". Entonces, ¿qué tal esta página de atollic.com "¿Por qué el análisis de cobertura de código?"
Esto parece ser bastante relevante aquí. Si tiene un conjunto de casos de prueba que logra alcanzar un cierto nivel de cobertura (código o de otro tipo), entonces es muy probable que invoque el código bajo prueba con un conjunto bastante exhaustivo de valores de entrada. Esto no le dirá mucho sobre el código bajo prueba (a menos que el código explote o genere fallas detectables) pero le da confianza en su conjunto de casos de prueba .
En un interesante cambio de vista de Necker Cube , ¡el código de prueba ahora está siendo probado por el código bajo prueba!
fuente
Hay muchas formas de garantizar que un programa haga lo que desea y de garantizar que las modificaciones no tengan efectos no deseados.
La prueba es una. Evitar la mutación de datos es otra. Entonces es un sistema de tipos. O verificación formal.
Entonces, si bien estoy de acuerdo en que las pruebas son generalmente algo bueno, un porcentaje dado de pruebas podría no significar mucho. Prefiero confiar en algo escrito en Haskell sin pruebas que en una biblioteca PHP bien probada
fuente