unitarias unit tutorial test que pruebas net integracion unit-testing legacy-code

unit-testing - tutorial - que es xunit



Agregar pruebas unitarias al código heredado (8)

Eche un vistazo a la libre biblioteca de utilidad de pruebas de unidades de fuente abierta, ApprovalTests . Si usted es un desarrollador de .NET, el creador, Llewellyn Falco, ha realizado una serie de videos que muestran cómo usa ApprovalTests para mejorar las pruebas unitarias para el código nuevo y heredado.

¿Alguna vez ha agregado pruebas unitarias, después del hecho, al código heredado? ¿Qué tan complicado era el código y qué tan difícil era tropezar y burlarse de todo? ¿El resultado final valió la pena?


El libro de Michael Feathers "Working Effectively with Legacy Code" es un libro completo que cubre este tema. Michael afirma que a menudo es demasiado difícil introducir pruebas para el código heredado porque no está estructurado para ser comprobable. Lo que más obtuve del libro fue un par de patrones llamados "Funciones Sprout" y "Clases Sprout". Una función de brote es aquella que encapsula el cambio que necesita hacer en el código. Luego, prueba estas funciones solo por unidad. La clase de brotes es la misma idea, excepto que la nueva funcionalidad está contenida en una clase.


Hace un tiempo estuve hablando sobre la idea de la pirámide de pruebas revertidas en Legacy Code en XPDays http://xpdays.com.ua/archive/xp-days-ukraine-2012/materials/legacy-code/

Esta presentación debe responder a la pregunta de por qué es tan importante a veces comenzar con pruebas de integración / funcionales o incluso de alto nivel cuando se trabaja con código heredado. Y luego lentamente, paso a paso, presentando pruebas unitarias. No hay ejemplos de código, lo siento, pero puedes encontrar muchos de ellos en el libro de Michaels Feathers "Working effective with Legacy Code".

También puede consultar Legacy Code Retreat http://www.jbrains.ca/legacy-code-retreat y buscar esa reunión en su área.


La mejor manera, lo he encontrado, es agregar incrementalmente las pruebas unitarias, no solo saltar y decir que ahora vamos a probar la aplicación.

Entonces, si va a tocar el código, para corregir errores o refactorizar, primero escriba las pruebas unitarias. Para los errores las pruebas unitarias ayudarán a probar dónde está el problema, ya que puede duplicarlo.

Si está refactorizando, querrá escribir pruebas unitarias, pero puede descubrir que la prueba es imposible de escribir, por lo que es posible que necesite encontrar un nivel alto, que llame a la función que será refactorizada, y que la unidad pruebe esa parte. Luego, a medida que refactoriza la función ofensiva, escriba sus pruebas para asegurarse de que está funcionando como debería.

No hay una manera fácil de hacer esto.

Esta pregunta puede ayudar con más sugerencias. ¿Cómo se introducen las pruebas unitarias en una base de código heredada (C / C ++) grande?


Observe también el nuevo enfoque en el área de pruebas de unidad de código heredado: el proyecto Asis , está inspirado en el proyecto ApprovalTests y comparte sus conceptos clave.

Como se mencionó sobre el enfoque ApprovalTests en este artículo :

A menudo tiene un gran proyecto de código heredado en el que no tiene pruebas, pero tiene que cambiar el código para implementar una nueva característica o refactor. Lo interesante del código heredado es - ¡Funciona! Funciona durante años, sin importar cómo esté escrito. Y esta es una gran ventaja de ese código. Con las aprobaciones, con solo una prueba puede obtener todos los resultados posibles (HTML, XML, JSON, SQL o cualquier salida que pueda ser) y aprobar, porque ya sabe, ¡funciona! Una vez que haya completado dicha prueba y haya aprobado el resultado, estará mucho más seguro con una refactorización, ya que ahora "bloqueó" todo el comportamiento existente.

La herramienta Asis trata exactamente de mantener el código heredado mediante la creación y ejecución de pruebas de caracterización de forma automática.

Para más información, mire


Sí, y generalmente es doloroso. A menudo termino escribiendo pruebas de integración.

El libro The Art of Unit Testing tiene algunos buenos consejos sobre esto. También recomienda el libro Working Effectively with Legacy Code ; No he leído este último todavía, pero está en mi pila.

EDITAR: Pero sí, incluso la cobertura mínima del código valió la pena. Me dio confianza y una red de seguridad para refacturar el código.

EDITAR: Leí Working Workingly with Legacy Code, y es excelente.


Si planea refaccionar el código heredado, entonces la creación de esas pruebas unitarias es imprescindible. No se preocupe por la burla o el punteo: preocúpese de probar las entradas y salidas del sistema para que sus cambios o esfuerzos de refactorización no rompan la funcionalidad actual.

No te mentiré, la actualización de las pruebas unitarias al código heredado es difícil, pero vale la pena.


Una alternativa a las pruebas unitarias, también introducida en Working effective with legacy code son las pruebas de caracterización . Obtuve resultados interesantes con tales pruebas. Son más fáciles de configurar que las pruebas unitarias cuando se prueba desde un punto que se puede probar (llamado costura). El inconveniente es que cuando falla una prueba, tiene menos pistas sobre la ubicación del problema, ya que el área bajo prueba puede ser mucho más grande que con las pruebas unitarias. El registro ayuda aquí.

Un marco de prueba unitario como los de la familia xUnit se puede usar para escribir pruebas de caracterización.

En dichas pruebas, escritas después de los hechos, las afirmaciones verifican el comportamiento actual del código. A diferencia de las pruebas unitarias, no prueban que el código sea correcto, simplemente establecen (caracterizan) el comportamiento actual del código.

El proceso es similar al de TDD ,:

  • escribir una prueba para una parte del código
  • ejecutarlo - falla
  • corrige la prueba del comportamiento observado del código
  • ejecutarlo - pase
  • repetir

Las pruebas fallarán si modifica el comportamiento externo del código. Comportamiento externo del código? suena familiar ? Sí lo es, aquí estamos. Ahora puedes refactorizar el código.

Obviamente, el riesgo depende de la cobertura de las pruebas de caracterización.