Pruebas unitarias: aplicación acoplada a la base de datos

14

¿Cuál sería el mejor enfoque en la prueba unitaria de un modelo que se integra en una aplicación que está estrechamente unida a la base de datos?

El escenario específico aquí es un carrito de la compra. Me gustaría poder probar la eliminación y recuperación de elementos del carrito, así como la lógica de precios, etc. En mi opinión, todo esto requiere acceso a la base de datos, aunque he leído Varias veces debe evitarse el acceso a la base de datos.

    
pregunta user1189880 04.03.2012 - 09:53

8 respuestas

9

La inyección de dependencia es una forma de manejar esto. Puede configurar una base de datos de prueba para imitar el carrito de compras, o incluso puede escribir algún código que "confirme" la transacción del cliente. Luego, en el tiempo de ejecución, su software elegirá a qué componente conectarse.

¡No te conectes a la base de datos de producción para nada durante las pruebas!

    
respondido por el chrisaycock 04.03.2012 - 10:07
4

En la prueba de unidad, debe definir el límite de lo que está probando. Las pruebas unitarias son diferentes de las pruebas de integración. Si la lógica de precios es independiente del contenido del Carrito, entonces lo prueba por separado. Si este no es el caso, y todos los módulos están estrechamente acoplados, cree un entorno de prueba que imite la producción tanto como pueda y trabaje con eso. No creo que los atajos y la simulación ayuden a largo plazo.

    
respondido por el NoChance 04.03.2012 - 12:17
2

El modelo no debe depender de un DB (concreto). Si solo conoce una base de datos abstracta (lea "interfaz") que se entrega al modelo, puede reemplazar la base de datos con un objeto simulado .

  

En programación orientada a objetos , objetos simulados son objetos simulados que imitan la Comportamiento de objetos reales de forma controlada. Un programador generalmente crea un objeto simulado para probar el comportamiento de otro objeto, de la misma manera que un diseñador de autos usa un dummy de prueba de choque para simular el comportamiento dinámico de un humano en los impactos de vehículos ...

    
respondido por el EricSchaefer 04.03.2012 - 14:11
1

Tuve un problema similar: no tuve la posibilidad de garantizar que mi base de datos de prueba mantiene los valores. Así que en el futuro obtengo, por ejemplo, otros precios.

Extraje los datos que necesitaba en un pequeño sqlite -DB y usé este DB para mis pruebas. El Test-DB ahora es parte de la configuración de mi prueba de unidad.

    
respondido por el knut 04.03.2012 - 10:56
0

"Mejor" es subjetivo, pero puedes usar una conexión de prueba de db.

Use dispositivos para cargar algunos datos de prueba (productos de ejemplo para comprar) y luego escriba el caso de prueba para la clase / función que desea probar.

    
respondido por el AD7six 04.03.2012 - 10:05
0

Construí un complemento para Symfony 1.4 (PHP) para abordar este problema (entre otros). Se basa en el modo en que el marco de prueba de Django (Python) opera : framework crea y llena una base de datos de prueba separada antes de que comience cada prueba, y destruye la base de datos de prueba una vez que se completa cada prueba.

Tenía un par de preocupaciones sobre esta estrategia, tanto en términos de rendimiento (si el esquema no cambia, ¿por qué no simplemente borra los datos en lugar de reconstruir toda la estructura?) y la conveniencia (a veces quiero inspeccionar la estructura) base de datos después de una prueba fallida, así que no la destruyas indiscriminadamente), por lo que adopté un enfoque ligeramente diferente.

Antes de que se ejecute la primera prueba, la base de datos se destruye y se reconstruye, en caso de que haya cambios en el modelo desde la última prueba. Antes de que se ejecute cada prueba subsiguiente, los datos en la base de datos se borran, pero la estructura no se reconstruye (aunque se puede iniciar una reconstrucción manual desde una prueba si es necesario).

Al cargar de forma selectiva los datos en cada prueba, uno puede crear el entorno adecuado para esa prueba sin interferir con las pruebas posteriores. Los archivos de aparatos también pueden reutilizarse, lo que hace que esta tarea sea mucho menos onerosa (¡aunque es mi parte menos favorita de las pruebas de escritura!).

En ambos marcos de prueba, el adaptador de base de datos está configurado para usar la conexión de prueba en lugar de la conexión de "producción" para evitar que la ejecución de la prueba corrompa los datos existentes.

    
respondido por el user34530 05.03.2012 - 22:29
0

Yo diría, simplemente siga adelante y use dispositivos para precargar los datos. Es así como los marcos de prueba de unidad parecen funcionar en general, al probar la manipulación de datos.

Pero si realmente desea evitar tener que conectarse a una base de datos de cualquier tipo y seguir la definición demasiado estricta de que las pruebas unitarias no tocan nada fuera del código, eche un vistazo a la burla del objeto. ustedes ideas.

Por ejemplo, en lugar de colocar el SQL directamente en el código donde lo necesita, tenga una forma de llamar a un método que haga solo lo que hace el SQL. Utilice Person.getPhoneNumber() , por ejemplo, en lugar de SELECT phone_number FROM person WHERE id = <foo> . No solo es más claro y más fácil de entender de un vistazo, sino que, durante las pruebas, puede burlarse del objeto Person para que getPhoneNumber() siempre devuelva 555-555-5555 o algo así, en lugar de tocar la base de datos.

    
respondido por el Izkata 05.03.2012 - 23:15
0

Esto es bastante fácil de hacer con Junit si es un poco largo.

La "configuración" debe definir y completar un conjunto de tablas temporales.

Luego puede realizar las pruebas de unidad para todas las actualizaciones, insertar, eliminar funcionalidad.

Para cada prueba, usted llama a su método de actualización y luego ejecuta algo de SQL para verificar el resultado esperado.

En la fase de "desmontaje", se eliminan todas las tablas.

De esta manera, siempre se ejecutan las mismas pruebas en los mismos datos iniciales. Si mantiene las tablas entre las pruebas, terminan siendo "contaminadas" por pruebas fallidas, además, es casi imposible realizar una prueba de "inserción" consistente, ya que necesita inventar nuevas claves en cada prueba.

    
respondido por el James Anderson 22.09.2013 - 04:48

Lea otras preguntas en las etiquetas