java database testing scala dbunit

¿Hay un marco similar a dbunit que no aspire para java/scala?



database testing (13)

Acabo de lanzar un marco basado en DSL groovy llamado pedal-loader disponible a través de github . Documentación here .

Le permite trabajar directamente con la abstracción de nivel de entidad JPA. Como es una secuencia de comandos groovy, puedes usar todas las construcciones groovy.

Para insertar filas en una tabla respaldada por una entidad JPA llamada Estudiante, con campos (no columnas de bases de datos, pero campos mapeados) llamados id, name y grade, harías algo como esto:

allStudents = table(Student, [''id'', ''name'', ''grade'']) { row 1, ''Joe'', Grade.A rowOfInterest = row 2, ''John'', Grade.B }

Grade es una enumeración en la clase de Estudiante que está mapeada en la columna de la base de datos (tal vez usando la anotación de JPA 2.1 @Convert). allStudents es una lista que contendrá las filas y rowOfInterest es una referencia a una fila en particular. Estas propiedades (allStudents y rowOfInterest) están disponibles para su prueba unitaria.

Estaba pensando en crear un nuevo marco de población de base de datos ligero. Odio absolutamente a dbunit. Antes de hacerlo, quiero saber si alguien ya lo hizo.

Cosas que no me gustan de dbunit:

1) El formato más simple para escribir y comenzar está en desuso. Quieren que uses formatos que están hinchados. Algunos incluso requieren esquemas xml. Sí lo que sea.

2) Llenan las filas no en el orden en que las escribes, sino que en el orden las tablas se definen en el archivo xml. Esto es realmente malo porque no puede ordenar sus datos de tal manera que las restricciones de clave externa no causen problemas. Esto solo te obliga a pasar por la molestia de apagarlos por completo.

Esto también desperdicia tiempo e hincha las clases base de junit para incluir código y deshabilitar las restricciones de clave externa. Probablemente tendrá que probar el tipo de base de datos (hsqldb, etc.) y deshabilitarlos en formas específicas de la base de datos. Esto es muy malo.

Podría ser mejor si dbunit ayudó a deshabilitar las restricciones de clave externa como parte de su marco de trabajo automáticamente, pero no lo hacen. Ellos hacen un seguimiento de los dialectos ... ¿por qué no los utilizan para esto? En última instancia, todo esto hace que el programador pierda tiempo y no se levante y realice pruebas rápidamente.

3) XML es un dolor para escribir. No necesito decir más sobre esto. También ofrecen tantas maneras de hacerlo, que creo que simplemente complica las cosas. Solo ofrezca una manera realmente sólida y termine con eso.

4) Cuando sus datos se vuelven grandes, hacer un seguimiento de los identificadores y sus relaciones consistentes / correctas es un dolor real.

Además, si no trabaja en un proyecto durante un mes, ¿cómo debe recordar que user_id 1 era un administrador, user_id 2 era un usuario comercial, user_id 3 era ingeniero y user_id 4 era algo más? Volver a comprobar esto está perdiendo más tiempo. Debe haber una manera significativa de recuperarlo que no sea un número arbitrario.

5) Es lento. Descubrí que, a menos que se use hsqldb, es dolorosamente lento. No tiene que ser así. También existen numerosas formas de desordenar su configuración, ya que no es fácil hacerlo "de fábrica". Hay una joroba que debes atravesar para que funcione bien. Todo lo que hace es alentar a la gente a no usarlo, o enojarse cuando empiezan a usarlo.

6) Algunos valores tienden a repetir mucho, le gustan las fechas. Sería bueno especificar los valores predeterminados, o incluso hacer que el marco ponga los valores predeterminados de forma automática, incluso sin que usted le diga que ponga los valores predeterminados allí. De esta forma, puede crear objetos solo con los valores que desea, y dejar el resto apagado. Esto es mejor que especificar cada rincón de una columna si no es necesario.

7) Probablemente, lo más molesto es que la primera entrada debe incluir TODOS los valores, incluso los marcadores de posición nulos, o las filas futuras no seleccionarán las columnas que usted realmente especificó.

DBunit tampoco tiene un valor predeterminado sensato para traducir [NULL] a un valor nulo real. Tienes que agregarlo manualmente. Dime, ¿quién no ha hecho esto con dbunit? Todos tienen. ¡No debería ser así!

Lo que esto significa es que si tiene un objeto polimórfico, debe declarar todas las claves externas a las tablas de unión de cada subclase en la primera fila, aunque sean nulas. Si hace una tabla para todos los patrones de subclases, aún debe especificar todos los campos en la primera fila. Esto es horrible.

¿Hay algo por ahí para satisfacerme, o debería convertirme en el próximo desarrollador de frameworks de un framework de pruebas de bases de datos mucho mejor?


Acabo de lanzar una biblioteca llamada JDBDT (Java Database Delta Testing) que puede usar para la configuración y validación de bases de datos en pruebas de software.

Eche un vistazo a http://jdbdt.org

Mejor, Eduardo


Aquí hay una breve lista de algunas herramientas en este sentido (además de DBunit) que me gustan especialmente, o me parecen interesantes. Por lo menos, pueden ofrecer algo de inspiración:

Tenga en cuenta que ninguno de estos son realmente competidores de DBunit en términos de alcance o conjunto de características. Sin embargo, hay algunas ideas interesantes que vale la pena echarle un vistazo. ¡Buena suerte!


Como desarrollador de DbUnit, estoy agradecido por las críticas y estoy parcialmente de acuerdo con usted. Actualmente estamos comenzando el diseño del próximo lanzamiento principal de DbUnit y deseo invitarlo a participar tanto en la discusión como en el desarrollo.

No voy a responder sus puntos ya que su pregunta no está realmente relacionada con DbUnit, sino con las alternativas de DbUnit. De todos modos, solo quiero resaltar que su punto 7 es completamente falso: ya no necesita especificar todas las columnas en la primera fila, la característica se llama detección de columnas. No voy a decirte por qué no está habilitado por defecto ya que seguramente eres lo suficientemente inteligente como para entenderlo por ti mismo.

Le haré un examen profundo a scaladbtest con la esperanza de que podamos integrar sus ideas.


Enfrentando preocupaciones similares al usar DBUnit, he encontrado esto: http://dbsetup.ninja-squad.com/index.html que puede abordar las preocupaciones. Por ejemplo, en lugar de representar datos de prueba en archivos separados, todo el contenido de DB está contenido dentro de la clase java.


Estás haciendo un excelente punto.

He estado trabajando para muchos portales web en los últimos años, principalmente con PHP, pero también algo de Java de vez en cuando.
Y, como usted, no entiendo eso después de todos estos años los desarrolladores de Framework y Unittesting no parecen darse cuenta de cuánto ha cambiado el manejo del almacenamiento en la última década. ¡No es suficiente simplemente enviar sentencias de creación / inserción / truncamiento a alguna base de datos! Si está operando a gran escala, termina empleando todo tipo de backends de almacenamiento, organizados en capas para expulsar rápidamente el contenido caliente. Además, en el frente de la Base de datos está el tema de la partición de datos. Si no tiene una abstracción de clave externa adecuada, seguramente se volverá loco cuando cambie su configuración de almacenamiento. Y mientras estamos en eso: el orden de aparatos por precedencia de clave extranjera tiene muchas dificultades y todavía no he visto una solución real para eso con DBUnit .

De todos modos, el punto es tener solo un almacenamiento básico de base de datos para que las pruebas unitarias no sean suficientes para configuraciones de almacenamiento complejas, ya que a menudo no reproducen problemas en el entorno en vivo y son un lastre para mantener.

Sin querer sonar como un fanboy: un lugar donde las cosas están bien es ruby on rails . Eso tiene un concepto de modelo persistente que la gente parece haber pensado un poco. Si se trata de PHP , Symfony es el lugar a donde ir. Está limitado por la inclusión predeterminada de Doctrine , con también bastante centrado en DB, pero tiene interfaces limpias y una gran capacidad de extensión, y ha copiado por completo el sistema de accesorios de rieles. Profesionalmente, tengo que apegarme a las soluciones de homebrew por ahora, pero funcionan bien.


Estamos escribiendo Daleq como un envoltorio alrededor de DbUnit para abordar algunas de las preocupaciones mencionadas. Permite llenar un DB solo dentro de la prueba de su unidad en lugar de depender de la edición de archivos XML.


La situación de DBUnit es a veces frustrante. Algunos de los problemas se resuelven en Marc Philipp con dbunit-datasetbuilder , especialmente si los combina con el validator , que se encuentra en una etapa muy temprana. Puedes verlo en acción en SZE .

Descargo de responsabilidad: Todos los recursos github mencionados son mantenidos por mí.


No conozco ninguna alternativa real a DbUnit y ninguna de las herramientas mencionadas por @Joe está en mi opinión:

  • Incanto : no DB agnóstico
  • SQLUnit : un arnés de prueba de regresión y unidad para probar los procedimientos almacenados en la base de datos (eso no es de lo que trata DbUnit)
  • Cactus : una herramienta para pruebas en contenedor (no veo dónde ayuda con las bases de datos)
  • Liquibase : una herramienta de migración de base de datos (no carga / verifica datos)
  • ORMUnit : puede inicializar una base de datos pero eso es todo
  • JMock : no compite con DbUnit en absoluto

Dicho esto, personalmente he usado DbUnit con éxito varias veces, en proyectos pequeños y grandes, y me parece bastante utilizable, especialmente cuando se usa Unitils y su módulo Unitils . Esto no significa que sea perfecto y no se puede mejorar, pero con herramientas decentes (ya sea por encargo o algo así como Unitils), usarlo ha sido una experiencia decente.

Así que déjame responder algunos de tus puntos:

1) El formato más simple para escribir y comenzar está en desuso. Quieren que uses formatos que están hinchados. Algunos incluso requieren esquemas xml. Sí lo que sea.

DbUnit admite XML planas o estructuradas, XLS, CSV. ¿Qué formato revolucionario te gustaría usar? Por cierto, una DTD o esquema no es obligatorio cuando se usa XML. Pero te da cosas buenas como la validación y el autocompletado, ¿cómo es eso malo? Y Unitils puede generarlo fácilmente para usted, vea Generar un XSD o DTD de la estructura de la base de datos .

Podría ser mejor si dbunit ayudó a deshabilitar las restricciones de clave externa como parte de su marco de trabajo automáticamente, pero no lo hacen. Ellos hacen un seguimiento de los dialectos ... ¿por qué no los utilizan para esto? En última instancia, todo esto hace que el programador pierda tiempo y no se levante y realice pruebas rápidamente.

Están esperando tu parche.

Mientras tanto, Unitils proporciona soporte para manejar restricciones de forma transparente, consulte Deshabilitar restricciones y actualizar secuencias .

3) XML es un dolor para escribir. No necesito decir más sobre esto. También ofrecen tantas maneras de hacerlo, que creo que simplemente complica las cosas. Solo ofrezca una manera realmente sólida y termine con eso.

Creo que el dolor es subjetivo, pero no me resulta doloroso, especialmente cuando uso un esquema y autocompletado. ¿Cuál es la bala de plata que estás sugiriendo?

4) Cuando sus datos se vuelven grandes, hacer un seguimiento de los identificadores y sus relaciones consistentes / correctas es un dolor real.

Mantenlos pequeños, esa es una buena práctica conocida. Vas contra una buena práctica conocida y luego te quejas ...

Además, si no trabaja en un proyecto durante un mes, ¿cómo debe recordar que user_id 1 era un administrador, user_id 2 era un usuario comercial, user_id 3 era ingeniero y user_id 4 era algo más? Volver a comprobar esto está perdiendo más tiempo. Debe haber una manera significativa de recuperarlo que no sea un número arbitrario.

Sí, el cambio de tareas es contraproducente. Pero como trabajas con datos de bajo nivel, debes saber cómo se representan, no existe una solución mágica a menos que uses una API de nivel superior, por supuesto (pero ese no es el propósito de DbUnit).

5) Es lento. Descubrí que, a menos que se use hsqldb, es dolorosamente lento. No tiene que ser así. También existen numerosas formas de desordenar su configuración, ya que no es fácil hacerlo "de fábrica". Hay una joroba que debes atravesar para que funcione bien. Todo lo que hace es alentar a la gente a no usarlo, o enojarse cuando empiezan a usarlo.

Eso es inherente a las bases de datos y JDBC, no a DbUnit. Use una base de datos rápida como H2 si desea que las cosas sean lo más rápidas posible (si tiene una mejor manera agnóstica de hacer las cosas, me gustaría saber más).

6) Probablemente, lo más molesto es que la primera entrada debe incluir TODOS los valores, incluso los marcadores de posición nulos, o las filas futuras no seleccionarán las columnas que usted realmente especificó.

No cuando se usa Unitils como se menciona en presentaciones como Unitils - Home - JavaPolis 2008 o Unit testing: unitils y dbmaintain .

¿Hay algo por ahí para satisfacerme, o debería convertirme en el próximo desarrollador de frameworks de un framework de pruebas de bases de datos mucho mejor?

Si crees que puedes mejorar las cosas, tal vez contribuyas a las soluciones existentes. Si eso no es posible y si crees que puedes crear el marco de prueba de la base de datos asesino, qué puedo decir, hazlo. Pero no lo olvide, el despotricar es fácil, encontrar soluciones usando sus propias soluciones es mucho menos.


Si usa Spring Framework (o no le importa usarlo al menos para realizar pruebas), Spring DBUnit es actualmente la mejor alternativa (mantenida) a DBUnit que conozco y uso. Citando su sitio web:

Spring DBUnit proporciona integración entre el marco de prueba Spring y el popular proyecto DBUnit. Le permite configurar y desmontar tablas de base de datos usando anotaciones simples, así como también verificar los contenidos de la tabla esperada una vez que finaliza una prueba.

Spring DBUnit parece ser la solución de Spring ''algo oficial'' para las pruebas de unidades DB (con DBUnit); al menos el autor / mantenedor de la biblioteca, Phil Webb, está trabajando en SpringSource / Pivotal.


Uso DBUnit, con algunas envolturas para suavizar los bordes ásperos. Una buena herramienta que puede complementar o superponer la funcionalidad es Jailer . Puede extraer subconjuntos de datos de una base de datos de referencia y almacenarlos como archivos XML compatibles con DBUnit o como "archivos DML clasificados topológicamente", que respetan las restricciones de clave externa.


Yo también tuve problemas similares con DBUnit. Especialmente para usarlo para poblar datos de desarrollo local y exportar datos de una base de datos real. Me encontré con varios casos en los que exportaría un conjunto de datos que no podría importar.

Esto me inspiró a escribir una nueva biblioteca para ello: https://github.com/jeffskj/phonydata

Utiliza un DSL maravilloso para definir los conjuntos de datos, lo que permite una representación muy compacta de los datos y permite hacer cosas geniales, como generar datos aleatorios, ya que se trata de un código groovy.


Aquí puede encontrar una alternativa que usa la configuración de Spring y la prueba de Specs2 .