2010-11-15 11 views
6

En mi código, yo interactúo con una base de datos (que no forma parte de mi archivo de solución). La base de datos es propiedad de un equipo separado de DBA, y el código que los desarrolladores escriben solo puede acceder a los procesos almacenados. Sin embargo, tenemos una vista completa de los procesos, tablas y columnas de la base de datos (su definición). Para mi código que depende de los datos, actualmente escribo pruebas unitarias que modifican los datos en las tablas (y elimino esas filas después de que se realiza la prueba unitaria), de modo que puedo ejecutar pruebas unitarias para ejercitar mi código que interactúa con el DB. Todo el código para hacer esto está en el archivo de prueba (especialmente en las funciones ClassInitialize() y ClassCleanup()). Sin embargo, mis nuevos compañeros de trabajo me han dado una gran cantidad de dolor, calificando mi estilo de pruebas unitarias como "destructivo" porque leo/escribo en la base de datos dev insertando y eliminando filas. En el momento en que codificamos las pruebas unitarias, el diseño de la base de datos generalmente no es estable, por lo que muchas veces podemos encontrar problemas en el código de proceso almacenado antes de desatar el departamento de control de calidad en nuestros programas (ahorra recursos). Todos me dicen que hay una forma de clonar la base de datos en la memoria en el momento en que se ejecutan las pruebas de la unidad MSTest, sin embargo, no saben cómo hacerlo. Investigué en la web y no puedo encontrar la forma de hacer lo que mis compañeros de trabajo necesitan que haga.MSTest pruebas de unidad y acceso a la base de datos sin tocar la base de datos real

¿Puede alguien decirme con certeza si esto puede ocurrir en el entorno que mencioné anteriormente? Si es así, ¿puedes señalarme en la dirección correcta?

Respuesta

1

Incluso con una recompensa, no pude averiguar si esto existe. Supongo que en este punto, las personas que me dijeron que esta tecnología existe podrían haber estado equivocadas.

1

Me burlaría de la base de datos, en lugar de tratar de interactuar con una instancia de prueba. Esto hará que tus pruebas sean más rápidas (por lo que es más probable que las ejecutes).

+0

¿Estás diciendo "simulacro" como en un clon o espejo? Si es así, eso es lo que estamos tratando de hacer. Cree una versión en memoria de la base de datos para que el código interactúe. ¿Cómo se hace esto? – DMCS

+0

No, digo falso como en una base de datos falsa, algo que actúa como una base de datos, pero puede establecer su comportamiento en las pruebas. –

+0

Me costará mucho trabajo realizar una ingeniería inversa de la base de datos del DBA cada vez que quiera ejecutar las pruebas unitarias. Hay una gran cantidad de código complejo que ocurre en los procesos almacenados del DBA, así como muchas tablas y columnas para reproducir cada vez. ¿No hay una herramienta para hacer esto por nosotros en VS2010? – DMCS

4

Si puede crear una "costura" entre el código de lógica de negocios y su capa de acceso a datos, debería estar bien. Usa interfaces para representar el contrato que tu DAL expone a tu lógica de negocios y luego escribe tu propio conjunto de objetos falsos o utiliza una herramienta de burla como rinocerontes.

Si está escribiendo pruebas que llegan a esa base de datos, entonces tiene un gran problema de mantenimiento, ya que como dice, la base de datos está cambiando y dificulta el mantenimiento de un entorno que tenga acceso a la base de datos. Lo que está escribiendo en realidad son pruebas de integración, que aún son válidas, pero las pruebas verdaderas de la unidad no deben tener dependencias en bases de datos, sistema de archivos, etc.

+0

Sí, tenemos una "costura" de géneros. Hay una DAL (costura) que se compone de una clase estática con funciones estáticas para llamar a funciones atómicas desde y hacia la base de datos. No estoy seguro de cómo extraer una interfaz para funciones estáticas. Si se trata de pruebas de integración, ¿cómo haríamos pruebas unitarias sin permitir que el código se comunique con el DAL? – DMCS

+0

Estático = estrechamente acoplado = no desmontable (a menos que use [Typemock] (http://www.typemock.com/)). Necesitará refactorizar su código para usar el [Repository Pattern] (http://stackoverflow.com/questions/3175/repository-pattern-tutorial-in-c) o alguna variante. Ben tiene razón en que esto te ahorrará dolores de cabeza. Sin embargo, recomiendo [Moq] (http://code.google.com/p/moq/) sobre Rhino. :) – TrueWill

1

Suponiendo que no puede hacer lo que otros sugirieron porque en realidad está probando los procedimientos almacenados hacen lo que espera, entonces creo que a lo que se refieren sus colegas es a usar una base de datos en memoria.

Cuando la gente habla de las bases de datos en memoria para las pruebas, generalmente se refieren a SQLite. Construyen la base de datos en la memoria al comienzo de la prueba y la destruyen al final. Desafortunadamente, SQLite no es compatible con los procedimientos almacenados, por lo que no lo ayudará.

Lo que yo sugeriría es que escriba pruebas de integración específicas para los Procedimientos almacenados e inserte/elimine datos como lo hace actualmente. Tenga en cuenta que es más fácil si ajusta la prueba en una transacción que luego revierte. También puede usar las funciones de "pruebas de unidades" de la base de datos en Visual Studio para probar las extensiones si tiene eso disponible.

Para el resto de su código, simule su DAL ya que @Ben sugirió y pruebe su lógica comercial como una prueba de unidad normal. Sin embargo, dada la complejidad de que su DAL sea una clase estática, tendrá que trabajar un poco para ajustar el DAL y comenzar a usar la clase contenedora en toda la aplicación, algo parecido a cómo trata ASP.NET MVC con HttpContext.

+0

Correcto, no puedo hacer lo que las otras personas han sugerido. De ahí la recompensa que coloqué sobre esta pregunta. También modifiqué la pregunta para enfatizar la pregunta que hice. Como se señaló en otras respuestas, MOC'ing no es una buena opción porque los DBA pueden cambiar los sprocs de la base de datos, los nombres de las tablas, los nombres de las columnas, etc. en cualquier momento. Y una interacción con la base de datos de MOC no detectará estos tipos de cambios sutiles por parte de los DBA. Una prueba unitaria que pruebe la configuración/esquema/datos actuales de la base de datos será una gran solución de problemas adicional cuando nuestro dev env env caiga, identificando rápidamente el punto de falla. – DMCS

+0

No creo que una base de datos en memoria sea una opción en su caso. En algún momento debe probar la comunicación de su base de datos real, y debe probar contra la realidad. Tiene dos opciones como se describe aquí: Prueba contra una base de datos común/real y ajuste sus pruebas dentro de una transacción y reversión. El otro es usar una base de datos privada. Si la base de datos común se utiliza para otros fines que no sean las pruebas, como es obvio, recomiendo encarecidamente el enfoque de la base de datos privada. Entonces puedes hacer lo que quieras con él. –

6

¿Tiene scripts SQL que se pueden usar para crear su base de datos? Deberías haberlo hecho, y deberían estar bajo control de versión.Si es así, entonces usted puede hacer lo siguiente:

En su prueba de código de configuración:

  • crear una base de datos 'temporal' usando los scripts SQL. Use un nombre único, por ejemplo unitTestDatabase_ [timestamp].
  • configure los datos que necesita para su prueba en la base de datos de prueba. Lo ideal sería utilizar las funciones públicas de la API (por ejemplo, CreateUser, AddNewCustomer), pero donde la API requerida no existe, use los comandos SQL. El uso de la API para configurar los datos de prueba hace que las pruebas sean más robustas frente a los cambios en la implementación de bajo nivel (es decir, el esquema de la base de datos). Esta es una razón por la cual escribimos pruebas unitarias para garantizar que los cambios en la implementación no rompan la funcionalidad.
  • ejecute sus pruebas unitarias, usando la inyección de dependencia para pasar la cadena de conexión de la base de datos de prueba del código de prueba al código bajo prueba.

y en el código de desmontaje prueba, eliminar la base de datos. Lo ideal sería hacerlo usando los scripts de desinstalación de la base de datos, que también deberían estar bajo control de versión.

Puede controlar la frecuencia con la que desea crear una base de datos de prueba unitaria: p. Ej. por proyecto de prueba, clase de prueba o método de prueba, o una combinación, creando la base de datos en un método [AssemblyInitialize], [ClassInitialize] o [TestInitialize].

Esta es una técnica que utilizamos con gran éxito. Las ventajas son:

  • cada vez que corremos las pruebas unitarias, estamos probando que nuestros scripts de instalación de base de datos trabajan en conjunto con el código.
  • aislamiento de prueba, es decir, las pruebas solo afectan a su base de datos de prueba. Y no importa si el código de reversión falla, no está tocando los datos de otra persona.
  • Confianza en el código. Es decir, porque estamos usando una base de datos real, las pruebas de unidad me dan más confianza de que el código funciona que si estuviera burlando de la base de datos. Por supuesto, esto depende de qué tan bueno sea su conjunto de pruebas de componentes/integración de nivel superior.

Desventajas:

  • las pruebas de unidad son dependientes de un sistema externo (el DBMS). Deberá encontrar el nombre de un DBMS en su código de configuración de prueba. Esto se puede hacer utilizando un archivo de configuración o mirando el tiempo de ejecución para ejecutar un DBMS local.
  • Los scripts de instalación de la base de datos pueden ralentizar las pruebas. Según nuestra experiencia, las pruebas todavía se están ejecutando con la suficiente rapidez y hay muchas oportunidades para optimizarlas. Ejecutamos nuestro conjunto de pruebas de aproximadamente 400 unidades en aproximadamente 1 minuto, que incluye la creación de 5 bases de datos separadas en una instalación local de SQLServer 2008.
+0

No, los guiones pertenecen a los DBA. Son un departamento diferente. Gestión diferente Así que necesitaré una herramienta que realice ingeniería inversa en la base de datos y pueda crearla sobre la marcha en la memoria o en una instalación local de SQL Server de algún tipo. Gracias por los punteros en [AssemblyInitialize] y [ClassInitialize] ya que puedo hacer un buen uso de estos en otras pruebas unitarias :) :) – DMCS

Cuestiones relacionadas