2009-07-10 9 views
16

¿Cuál es la mejor forma de probar en unidades middleware .NET dependiente de una gran base de datos? P.ej. ¿un proceso que lee datos de múltiples bases de datos, lo manipula y luego lo combina y lo escribe en otras bases de datos?Base de datos de pruebas unitarias Aplicaciones .NET

¿Las bases de datos deben llenarse con datos estáticos que de alguna manera se restablecen en cada ejecución de prueba de la unidad? ¿Debería burlarse de todo el acceso al SQL Server? ¿No es factible probar en una unidad tal aplicación en el mundo real?

+1

Creo que las pruebas de interacción funcionarían mejor aquí – IAdapter

+5

Dado que hay tanto interés en un tema tan común y simple, sugeriría que habría un gran mercado para un estudio de caso o un libro sobre este tema. Afecta a casi todos los desarrolladores de .NET y, sin embargo, la información es incompleta y no comprobada.Sabemos cuáles son las mejores prácticas, pero en este escenario, ¿cómo se pueden implementar prácticamente las pruebas/burlas unitarias? –

Respuesta

5

La respuesta se burla de

Sin embargo, la manera de hacer esto que he encontrado es el siguiente.

Separe el DAL en 2 capas. La parte inferior simplemente realiza lectura atómica y escribe en las bases de datos; todos estos objetos implementan un conjunto de interfaces IReadFromDB e IWriteToDB.

Luego puede crear su lógica comercial de lectura y escritura en un nivel DAL más alto, en lugar de hacer referencia a los objetos que leerán y escribirán en la base de datos las interfaces y las propiedades de uso para sustituir la funcionalidad. Tiendo a incluir los objetos funcionales deseados en los constructores para que las cosas funcionen "de fábrica", por así decirlo.

Esto hará que sea muy fácil 'cambiar' la funcionalidad y así probar la lógica de la empresa.

En cuanto a las pruebas de lectura y escritura de la base de datos ... No he encontrado una manera que no implique el trabajo. Normalmente utilizo una cadena de conexión diferente a una copia de la base de datos y luego escribo la generación de datos y el código de limpieza para las pruebas unitarias para dejar el estado de la base de datos igual que antes y después.

Sí, lleva mucho tiempo ... sin embargo, no corre el riesgo de alejar a un cliente. Depende de tus prioridades

Alguien más mencionó las pruebas de rendimiento. No consideraría esto como parte de una prueba unitaria. Normalmente hago esto con un arnés de prueba en combinación con el código de depuración simplemente porque el rendimiento de las piezas pequeñas a menudo es engañoso: cuando se pasa al panorama general, las partes que realmente son problemas de revestimiento a menudo no son las partes que marcarían las pruebas localizadas en mi experiencia .

2

Creo que la mejor práctica es realmente simular todo el acceso a la base de datos; simplemente devuelva algunos datos estáticos predeterminados en la llamada, no necesita probar cómo funcionan las bases de datos, su necesidad de probar el comportamiento de la unidad. En menor medida, la prueba de su unidad interactúa con el exterior, mejor.

Con burla tu podrás comprobar que la llamada a la base de datos es válida sin realmente invocarla, así que es lo que necesitas, creo.

+0

¿Cómo funcionaría esto en la práctica? La aplicación necesita un conjunto de datos de muestra para trabajar. Sin datos significa que no hará nada. ¿Cuál sería la mejor manera de almacenar esta muestra de datos y ponerla a disposición de la función que se está probando? No creo que las pruebas unitarias basadas en datos sean el camino a seguir (en caso de que alguien sugiera esto) ya que se trata de parámetros para funciones y valores devueltos, en lugar de la interacción de la función con la base de datos. –

+0

Imagine que tengo un método readUserData() que invoca una consulta de base de datos. Simplemente establezca un resguardo en esta consulta para devolver datos esenciales y verifique cómo se invocó esa consulta y cómo la unidad procesa los datos (cuál es el resultado de su trabajo). Así es como entendí esto. Tuve algunos ejemplos en mi vida usando objetos Moke pero solo en python ... –

+0

Mira la solución MrTortoise con capas separadas, es la mejor forma en que pienso de cómo puedes usar el acceso a la base de datos Moke. –

0

Debería tratar de aplicar capas a su código para que pueda simular el funcionamiento de sus funciones.

La capa que realmente necesita para hablar con la base de datos podría usar un sistema de configuración de datos y trabajar con ella dentro de una transacción, que se revertiría al final de la prueba.

1

Recomendaría burlarse del nivel de acceso a datos. El beneficio de usar simulaciones en esta instancia incluye: 1) las pruebas unitarias se ejecutarán más rápido. Si tienen que hacer el trabajo completo de conectarse a la base de datos, extraer datos, etc., el costo será caro. Pruebas costosas = ¡las personas dejan de ejecutarlas/comienzan a perder la fe en ellas! 2) Puede probar una amplia gama de escenarios sin tener que pasar por la molestia de configurar los datos de prueba/estáticos adecuados que debe asegurarse de que estén siempre en el DB antes de que comiencen las pruebas. 3) quitar el sistema db externo de la ecuación significa que está probando solo el código .NET que desea probar. Sin dependencia externa.

Puede tener una capa de acceso a datos que realice una interacción db pura, y luego simular eso. O bien, use simuladores SqlCommands, etc. en su código .NET.

1

Creo que debe separar sus preocupaciones en diferentes tipos de pruebas.

  • Pruebas de unidad de escritura para la lógica de manipulación de datos implementada en .NET. O simula las bases de datos o separa por completo la lógica de masaje de datos del material de acceso a los datos, y solo alimenta tu rutina de manipulación de datos con los datos de entrada precocidos.
  • Crea una prueba de integración que ejercita todo el flujo de datos. Esta prueba también debe ser automática. Configure las bases de datos de origen y destino (ya sea desde el script DB o desde la copia de seguridad de la base de datos) a un estado conocido, ejecute su lógica de manipulación de datos y luego verifique los resultados.
  • Es posible que también desee crear pruebas de rendimiento y estrés si trabaja con muchos datos. Puede configurar una base de datos de la misma manera que lo hizo en la prueba de integración, generar un conjunto de datos de prueba, ejecutar su componente y verificar los tiempos de ejecución, o que finalice (por ejemplo, sin problemas de concurencia, puntos muertos, etc.)
0

Resumiré la capa de acceso a datos y luego me burlaré de ella. Con la burla, podrá aumentar la cobertura del código de sus pruebas. También evitará la idea de 'Test Cancer' que ocurrirá al hacer llamadas costosas a la red/sistema de archivos/base de datos porque la gente dejará de ejecutarlos.

Debe realizar algunas pruebas que llamen a la base de datos, pero deben limitarse lo más posible.

1

que tienen dos métodos para el código de la unidad de pruebas que tiene dependencias de bases de datos:

  • objetos Mock es decir TypeMock
  • scripts SQL personalizada que se ejecutan en el() submarinos TestInitialise() y TestCleanup.

Con Typemock, puedo datos de bases de datos falsos que entra en mi código, que me ayuda a ejecutar mis pruebas sin tener que preocuparse por la limpieza de la base de datos o restaurar copias de seguridad, etc. Yo uso burlarse de código de prueba fuera de la base de datos lógica, pero aún requiere datos falsos de la base de datos.

Con scripts SQL personalizados, puedo ejecutar comandos SQL en el sub TestInitialise() y, cuando la prueba de unidad finaliza, tengo el SQL de limpieza ejecutándose en el sub TestCleanup(). Utilizo este método para probar código donde la lógica de la base de datos es más complicada. Por ejemplo, podría necesitar insertar algunas filas en tablas que ayudarán a probar el código. Luego, en TestCleanup() tendré mis comandos SQL eliminados que eliminan todos los registros que se insertaron mediante el subprograma TestInitialise().

+0

Me gustan sus dos opciones. TypeMock (y similares) parecen ofrecer la posibilidad de agregar lo que quiero a las pruebas unitarias sin grandes cambios de código o arquitectura. Sin embargo, siento que si lo hubiera hecho "bien" no tendría que depender de estas costosas herramientas de terceros. Exactamente qué 'correcto' permanece abierto para discusión. –

0

En mi trabajo utilizamos Nunit y Typemock para nuestras pruebas unitarias. El hecho de que no necesitamos cambiar nuestro código para las pruebas es una gran ventaja. Burlarse del DAL es el camino a seguir.