test net framework example create asp c# tdd nunit

c# - net - Mover el código existente al desarrollo controlado por prueba



xunit c# example (5)

Habiendo descubierto recientemente este método de desarrollo, me parece una metodología bastante agradable. Entonces, para mi primer proyecto, tengo una pequeña DLL que vale código (en C # .NET, por lo que vale), y quiero hacer un conjunto de pruebas para este código, pero estoy un poco perdido en cuanto a cómo y donde empezar.

Estoy usando NUnit, y VS 2008, cualquier consejo sobre el tipo de clases para empezar, para qué escribir las pruebas y cualquier consejo sobre cómo mover el código hasta el desarrollo basado en pruebas sería muy apreciado.


El código comprobable es fácil de detectar, mediante las pruebas que lo acompañan. Si hay algunos, debe ser comprobable. Si no hay ninguno, asuma lo contrario. ;)

Dicho esto: Test Driven Development (TDD) no es tanto una estrategia de prueba como una estrategia de diseño. Las pruebas que escribe primero ayudan a diseñar la interfaz de sus clases, así como también a obtener el alcance de sus clases (o subsistemas).

Tener las pruebas que creó durante TDD y ejecutarlas más tarde hace buenas pruebas, pero es simplemente un efecto secundario (muy bienvenido) de esa filosofía de diseño.

Dicho esto, se espera que no se pruebe cierta resistencia de su código. Escuche su código y cambie la interfaz para poder probarlo fácilmente. Lo más probable es que lo rediseñes cuando comiences a escribir pruebas.


Lo llamo "Ingeniería inversa de prueba".

Comience "en la parte inferior": cada clase puede examinarse por separado y una prueba escrita para ella. En caso de duda, adivina.

Cuando haces TDD ordinario en la dirección de avance, tratas la prueba como sagrada y asumes que el código probablemente esté roto. Algunas veces la prueba es incorrecta, pero su posición inicial es que es el código.

Cuando estás haciendo TDRE, el código es sagrado, hasta que puedas probar que el código tiene un error de larga data. En el caso inverso, usted escribe pruebas alrededor del código, ajusta las pruebas hasta que funcionen y afirma que el código funciona.

Entonces, puedes profundizar en el código malo. Algunos malos cade tendrán casos de prueba sensibles, esto solo necesita ser limpiado. Sin embargo, algunos códigos incorrectos también tendrán un caso de prueba sin sentido. Esto puede ser un error o un diseño torpe que puede rectificar.

Para juzgar si el código es realmente incorrecto, también debe comenzar en la parte superior con casos de prueba generales. Los datos en vivo que realmente funcionan son un comienzo. Además, los datos en vivo que producen cualquiera de los errores conocidos, también son un buen lugar para comenzar.

He escrito pequeños generadores de código para convertir datos en vivo en casos de prueba unitaria. De esa manera, tengo una base consistente para probar y refactorizar.


Su DLL proporciona algún tipo de servicio. Para cada servicio, ¿qué debe hacer antes de obtener este servicio? ¿Qué parámetros debe pasar para obtener este servicio? ¿Cómo sabe que el servicio solicitado se ha ejecutado correctamente?

Una vez que tenga las respuestas a esas preguntas, puede escribir una primera prueba. Esas pruebas preferirían llamarse Pruebas de caracterización más que pruebas unitarias, pero probablemente serían más fáciles de escribir que las pruebas unitarias si la DLL no se desarrolló utilizando TDD.

Las pruebas de caracterización también se discuten en M. Feathers ''"Trabajando eficazmente con Legacy Code", que se recomienda en otras respuestas.

Además, asegúrese de escribir una prueba de falla antes de agregar cualquier nueva línea de código.


Trabajar eficazmente con Legacy Code es mi biblia cuando se trata de migrar código sin pruebas a un entorno probado por unidades, y también proporciona una gran cantidad de información sobre lo que hace que el código sea fácil de probar y cómo probarlo.

También encontré Test Driven Development por ejemplo y Pragmatic Unit Testing: en C # con NUnit para ser una introducción decente a las pruebas unitarias en ese entorno.

Un enfoque simple para iniciar TDD es comenzar a escribir pruebas primero a partir de hoy y asegurarse de que cada vez que necesite tocar su código existente (sin pruebas de unidad), escriba pruebas de aprobación que verifiquen el comportamiento existente del sistema antes de cambiar para que pueda volver a ejecutar esas pruebas después para aumentar su confianza en que no ha roto nada.


Vea el libro Working Effectively with Legacy Code de Michael Feathers.

En resumen, es mucho trabajo refactorizar el código existente en código comprobable y probado; A veces es demasiado trabajo ser práctico. Depende de qué tan grande es la base de código, y de cuánto dependen las diversas clases y funciones entre sí.

La refactorización sin pruebas introducirá cambios en el comportamiento (es decir, errores). Y los puristas dirán que en realidad no se está refaccionando debido a la falta de pruebas para verificar que el comportamiento no cambie.

En lugar de agregar pruebas en toda la plataforma a toda su aplicación a la vez, agregue pruebas cuando trabaje en un área de código. Lo más probable es que tenga que regresar a estos "puntos de acceso" nuevamente.

Agregue pruebas de abajo arriba: pruebe las clases y funciones pequeñas e independientes para verificar que sean correctas.

Agregue pruebas de arriba hacia abajo: pruebe subsistemas enteros como cuadros negros para ver si su comportamiento cambia con los cambios en el código. Y entonces puede pasar a través de ellos para descubrir qué está pasando. Este enfoque probablemente te beneficiará más.

Al principio, no se preocupe demasiado sobre cuál es el comportamiento "correcto" mientras agrega pruebas, busque detectar y evitar cambios en el comportamiento. Los sistemas grandes no probados a menudo tienen comportamientos internos que pueden parecer incorrectos, pero de los que dependen otras partes del sistema.

Piense en aislar dependencias como la base de datos, el sistema de archivos o la red, de modo que puedan intercambiarse entre los proveedores de datos simulados durante las pruebas.

Si el programa no tiene interfaces internas, líneas que definen el límite entre un subsistema / capa y otro, entonces puede que tenga que intentar introducirlas y probarlas.

Además, los marcos de burla automáticos como Rhinomocks o Moq pueden ayudar a burlarse de las clases existentes aquí. Realmente no he encontrado la necesidad de ellos en el código diseñado para la capacidad de prueba.