c# - Aplicación de base de datos de pruebas unitarias con lógica de negocios realizada en la interfaz de usuario
database unit-testing (11)
Comenzaría por usar alguna herramienta que probaría la aplicación a través de la IU. Hay una serie de herramientas que se pueden usar para crear scripts de prueba que simulan que el usuario haga clic en la aplicación.
También te sugiero que comiences a agregar pruebas unitarias a medida que agregas nuevas funcionalidades. Lleva mucho tiempo crear una cobertura completa una vez que se desarrolla la aplicación, pero si lo hace de forma incremental, entonces distribuye el esfuerzo.
Probamos las interacciones de la base de datos al tener una base de datos separada que se usa solo para pruebas unitarias. De esta forma, tenemos un conjunto de datos estáticos y controlables para que se puedan garantizar las solicitudes y las respuestas. Luego creamos el código c # para simular varios escenarios. Usamos nUnit para esto.
Administro una aplicación bastante grande (más de 50,000 líneas de código) y gestiona algunas acciones comerciales bastante críticas. Para describir el programa simple, diría que es una IU elegante con la capacidad de mostrar y cambiar los datos de la base de datos, y está administrando alrededor de 1.000 unidades de alquiler, y aproximadamente 3,000 inquilinos y todas las finanzas.
Cuando hago cambios, porque es una base de código tan grande, a veces rompo algo en otro lugar. Normalmente lo pruebo yendo a través de las cosas que cambié en el nivel funcional (es decir, ejecuto el programa y trabajo a través de la interfaz de usuario), pero no puedo probar para cada situación. Es por eso que quiero comenzar con las pruebas unitarias.
Sin embargo, este no es un verdadero programa de tres niveles con un nivel de base de datos, un nivel empresarial y un nivel UI. Gran parte de la lógica de negocios se realiza en las clases de UI, y se hacen muchas cosas en eventos. Para complicar las cosas, todo se basa en bases de datos, y no he visto (hasta ahora) buenas sugerencias sobre cómo probar las interacciones de la base de datos.
¿Cómo sería una buena manera de comenzar con las pruebas unitarias para esta aplicación? Tenga en cuenta. Nunca antes había hecho pruebas unitarias o TDD. ¿Debo reescribirlo para eliminar la lógica comercial de las clases de UI (mucho trabajo)? ¿O hay un mejor camino?
Creo que siempre es una buena idea separar la lógica de su negocio de la IU. Existen varios beneficios para esto, que incluyen pruebas de unidades y expansibilidad más sencillas. También puede consultar la programación basada en patrones. Aquí hay un enlace http://en.wikipedia.org/wiki/Design_pattern_(computer_science) que lo ayudará a comprender los patrones de diseño.
Una cosa que podría hacer por ahora es aislar todas las funciones de lógica de negocio y bases de negocios dentro de sus clases de UI y que dentro de cada constructor de UI o page_load tenga llamadas de prueba unitarias que prueben cada una de las funciones de negocio. Para una mejor legibilidad, puede aplicar la etiqueta #region alrededor de las funciones comerciales.
Para su beneficio a largo plazo, debe estudiar los patrones de diseño. Elija un patrón que se adapte a las necesidades de su proyecto y rehaga su proyecto usando el patrón de diseño.
Depende del idioma que estés usando. Pero, en general, comienza con una clase de prueba simple que utiliza algunos datos inventados (pero todavía algo ''real'') para probar tu código. Haz que simule lo que sucedería en la aplicación. Si está realizando un cambio en una parte particular de la aplicación, escriba algo que funcione antes de cambiar el código. Ahora que ya ha escrito el código de prueba, va a ser todo un desafío cuando intente probar toda la aplicación. Sugeriría empezar desde pequeño. Pero ahora, mientras escribe código, primero escriba pruebas de unidad y luego escriba su código. También podría considerar la posibilidad de refactorizar, pero sopesaría los costos de la refacturación frente a la reescritura un poco a medida que avanza las pruebas unitarias en el camino.
No hay mejor manera de comenzar las pruebas unitarias que probarlo : no lleva mucho tiempo, es divertido y adictivo. Pero solo si estás trabajando en un código comprobable .
Sin embargo, si intenta aprender las pruebas unitarias arreglando una aplicación como la que ha descrito de una sola vez, probablemente se sentirá frustrado y desalentado, y hay una buena posibilidad de que piense que las pruebas unitarias son una pérdida de tiempo. .
Recomiendo descargar un marco de pruebas unitarias, como NUnit o XUnit.Net . La mayoría de estos marcos tienen documentación en línea que brinda una breve introducción, como el inicio rápido de NUnit . Lea eso, luego elija una clase simple e independiente que:
- Tiene pocas o ninguna dependencia en otras clases, al menos no en clases complejas.
- Tiene algún comportamiento: un contenedor simple con muchas propiedades realmente no le mostrará mucho sobre las pruebas unitarias.
Intente escribir algunas pruebas para obtener una buena cobertura en esa clase, luego compile y ejecute las pruebas.
Una vez que se familiarice con eso, comience a buscar oportunidades para refactorizar su código existente , especialmente al agregar nuevas características o corregir errores. Cuando esas refactorizaciones conducen a clases que cumplen con los criterios anteriores, escriba algunas pruebas para ellos. Una vez que te acostumbras, puedes comenzar escribiendo pruebas .
No he intentado agregar pruebas para aplicaciones heredadas, ya que es realmente una tarea difícil. Si planea sacar parte de la lógica comercial de la interfaz de usuario y en una capa separada, puede agregar sus unidades de prueba iniciales aquí (refactorización y TDD). Si lo hace, le dará una introducción para crear una prueba unitaria para su sistema. Realmente es mucho trabajo, pero creo que es el mejor lugar para comenzar. Dado que es una aplicación basada en bases de datos, le sugiero que utilice algunas herramientas de burla y herramientas DBunit mientras crea su prueba para simular los problemas relacionados con la base de datos.
Primero, recomendaría leer un buen libro sobre pruebas unitarias, como The Art Of Unit Testing . En su caso, es un poco tarde para llevar a cabo el Desarrollo controlado por prueba en su código existente, pero si desea escribir las pruebas de su unidad a su alrededor, entonces esto es lo que recomendaría:
- Aísle el código que desea probar en bibliotecas de códigos (si aún no están en bibliotecas).
- Escriba los escenarios de casos de uso más comunes y tradúzcalos a una aplicación que use sus bibliotecas de códigos.
- Asegúrese de que su programa de prueba funcione como espera.
- Convierta su programa de prueba en pruebas unitarias usando un marco de prueba.
- Obtener la luz verde. De lo contrario, las pruebas de su unidad son defectuosas (suponiendo que funcionen las bibliotecas de códigos) y debe realizar algunas depuraciones.
- Aumente el código y la cobertura de escenarios de las pruebas de su unidad: ¿qué sucede si ingresa resultados inesperados?
- Obtener la luz verde de nuevo. Si la prueba de la unidad falla, es probable que la biblioteca de códigos no admita la cobertura de escenarios ampliados, ¡por lo que es un momento de refactorización!
Y para el código nuevo, le sugiero que lo intente usando Test Driven Development.
Buena suerte (¡lo necesitarás!)
Recomiendo leer el artículo Working Effectively With Legacy Code . Describe una estrategia viable para lo que estás tratando de lograr.
Recomiendo leer el libro Working Effectively with Legacy Code de Michael Feathers. Esto le mostrará muchas técnicas para aumentar gradualmente la cobertura de prueba en su base de código (y mejorar el diseño en el camino).
Refactorizar ES la mejor manera. Aunque el proceso es desalentador, definitivamente debe separar la presentación y la lógica comercial. No podrá escribir buenas pruebas unitarias contra su lógica de operaciones hasta que haga esa separación. Es tan simple como eso.
En el proceso de refactorización probablemente encontrará errores que ni siquiera sabía que existían y, al final, ¡sería un programador mucho mejor!
Además, una vez que refactorices tu código, notarás que probar tus interacciones de DB será mucho más fácil. Podrá escribir pruebas que realicen acciones como: "agregar nuevo inquilino", lo que implicará crear un objeto de inquilino simulado y guardar "él" en el db. Para la próxima prueba, escribiría "GetTenant" y trataría de obtener el inquilino que acaba de crear desde el archivo db y en su representación en memoria ... Luego compare su primer y segundo inquilino para asegurarse de que todos los campos coincidan con los valores. Etcétera etcétera.
TDD implica que construyas (y ejecutes) pruebas unitarias a medida que avanzas. Por lo que intenta hacer, agregue pruebas unitarias después del hecho, puede considerar usar algo como Typemock (un producto comercial). Además, es posible que haya creado un sistema que no se preste a pruebas unitarias, y en este caso, puede ser necesario realizar algunas (o muchas) operaciones de refactorización.
Una opción es esta: cada vez que aparece un error, escribe una prueba que te ayude a encontrar el error y resolver el problema. Haga que la prueba pase cuando se solucione el error. Luego, una vez que se resuelva el error, tienes una herramienta que te ayudará a detectar cambios futuros que podrían afectar la cantidad de código que acabas de arreglar. Con el tiempo, su cobertura de prueba mejorará y podrá ejecutar su conjunto de pruebas en constante crecimiento cada vez que realice un cambio potencialmente de gran alcance.