¿Le han ayudado los generadores de pruebas unitarias cuando trabaja con código heredado?

10

Estoy mirando una pequeña base de código C # (.NET 4.0, algo de Silverlight) (~ 70kLOC incluyendo generado) que tiene una cobertura de prueba muy baja. El código en sí funciona porque ha pasado las pruebas de aceptación del usuario, pero es frágil y en algunas áreas no está muy bien factorizado. Me gustaría agregar una cobertura de prueba de unidad sólida alrededor del código heredado utilizando los sospechosos habituales (NMock, NUnit, StatLight para los bits de Silverlight).

Mi enfoque normal es comenzar a trabajar en el proyecto, las pruebas unitarias y la refactorización, hasta que esté satisfecho con el estado del código. Lo he hecho muchas veces en el pasado y funcionó bien.

Sin embargo, esta vez estoy pensando en usar un generador de prueba (en particular, Pex ) para crear el marco de prueba, y luego desarrollarlo manualmente.

Mi pregunta es: ¿ha utilizado generadores de pruebas unitarias en el pasado al comenzar a trabajar en una base de código heredada y, de ser así, los recomendaría?

Mi temor es que las pruebas generadas pierdan los matices semánticos de la base de código, lo que lleva a la temida situación de tener pruebas por la métrica de cobertura, en lugar de pruebas que expresan claramente el comportamiento previsto en el código.

Duncan Bayne
fuente
Probé PeX una vez y los resultados fueron, bueno, digamos, no muy satisfactorios: YMMV. No espere que una herramienta de este tipo "entienda" su código y sus requisitos funcionales: no se pierde solo los "matices semánticos", se pierde toda la semántica. Además, cuando comienza con una base de código heredada, generalmente no comenzará primero con las pruebas unitarias, sino con las pruebas del sistema o de integración; eso definitivamente no es nada para lo que se creó PeX.
Doc Brown

Respuestas:

9

Sugeriría mirar las cosas un poco diferente. Agregar un nuevo código de prueba unitaria a una aplicación existente sin incidentes podría no brindarle los mejores resultados. Si está haciendo esto para familiarizarse con la base del código o si realmente tiene tiempo para matar y desea probar los generadores de prueba, ignore mis comentarios.

Para ser pragmático, debe revisar todas las listas de errores. Luego, cree pruebas unitarias para cada uno de los errores, lo que da como resultado cómo debería comportarse. Idealmente, solo agregaría un nuevo código para cada error a medida que lo alcanza.

Tiempos para agregar el código de prueba de la unidad:

  • Agregar nueva funcionalidad
  • Código refactorizado
  • Arreglado un error
  • Aprendiendo lo que hace el código
  • Probar que existe un error

Es difícil cuantificar el valor de agregar pruebas unitarias después del hecho.

Normalmente no me permito escribir respuestas que vayan en contra de lo que quiere el autor de la pregunta, pero creo que esta es una buena lección para transmitir.

Andrew T Finnell
fuente
Estoy 100% de acuerdo con usted allí; esta pregunta surgió de mí preguntándome cuál es la mejor manera de pasar un tiempo de inactividad. Mi práctica normal es probar y refactorizar en el proceso de corregir errores o agregar características. Esperaba que algunas personas pudieran compartir algunas historias de guerra en esta área ...
Duncan Bayne
1
+1, Disparar para cobertura después del hecho no suele ser productivo. Tener pruebas de errores corregidos que evitan la regresión es muy productivo. La regresión de un error puede ser muy frustrante para todos los involucrados. Las pruebas son realmente adecuadas para ayudarlo a escribir un mejor código. El atornillado en las pruebas generalmente resulta en pruebas de calidad inferior. Creo que el miedo del OP está fundado y la relación señal / ruido de las pruebas generadas simplemente se interpondrá en el camino. El código no probado probablemente tiene algunos bits muy ramificados. Las herramientas que señalan los olores del código son probablemente más útiles. Quizás FXCop y herramientas similares.
kevpie