2011-12-10 14 views
14

¿Cuáles son algunas de las mejores prácticas/principios a seguir, además de las recomendadas en el sitio real de dbunit, que pueden acelerar mucho las pruebas y mantenerlas mantenibles? Anhelo un library like factory girl para java, pero parece que no es posible debido a la tipificación estática.prácticas recomendadas de dbunit para el rendimiento

Mi pensamiento actual es tener 1 conjunto de datos xml por clase de prueba en este momento; tal vez comparta algunos de estos, y tal vez no. Si bien es posible que algunos datos de prueba se dupliquen en conjuntos de datos cruzados, me resulta demasiado difícil mantener conjuntos de datos compartidos en pruebas de 3000 unidades/integración, y aún me queda mucho más por recorrer.

Agradecería cualquier principio a seguir que conduzca a pruebas que funcionan bien y son fáciles de mantener.

+0

La pregunta es sobre el rendimiento, pero la verdadera preocupación parece ser "hacerlos mantenibles". En mi humilde opinión, debe centrarse absolutamente en la facilidad de mantenimiento y aumentar el rendimiento mediante la adición de más poder de cómputo. – Jayan

+2

Tenga en cuenta que si utiliza múltiples conjuntos de datos pequeños con DBUnit, puede encontrarse con un desagradable problema de fallas aleatorias. Escribí una [publicación de blog explicando por qué y cómo solucionarlo] (http://www.andrewspencer.net/2011/solve-foreign-key-problems-in-dbunit-test-data/). –

+0

Si anhela una Factory Girl para Java, eche un vistazo a https://github.com/mguymon/model-citizen – mguymon

Respuesta

8

En una de mis asignaciones anteriores tuvimos cientos de pruebas de integración con conjuntos de datos, aunque no en DBUnit — el entorno de prueba se escribió desde cero, ya que era una empresa muy grande que puede permitirse este tipo de cosas.

Los conjuntos de datos se organizaron jerárquicamente. El sistema bajo prueba consistió en unos pocos (5-10) módulos y los datos de prueba siguieron ese patrón. Una secuencia de comandos de prueba de unidad era la siguiente:

include(../../masterDataSet.txt) 
include(../moduleDataSet.txt) 

# unit-specific test data 
someProperty=someData 

Los nombres de propiedad se asignan directamente a los registros de base de datos por alguna herramienta extraña que no puedo recordar.

El mismo patrón se puede aplicar a las pruebas DBUnit. En conjunto de datos maestros puede colocar registros siempre debe ser — como diccionarios, la carga inicial de la base de datos, como si se va a instalar desde cero.

En conjunto de datos de módulo pondría registros que cubran casos de prueba de la mayoría de las pruebas en un módulo; No creo que una prueba promedio tuya involucre todas tus 70 tablas de base de datos, ¿o sí? Seguramente debe tener algunos grupos de funciones que podrían constituir un módulo, incluso si la aplicación es monolítica. Intenta organizar los datos de prueba a nivel de módulo a su alrededor.

Por último, en el nivel de prueba, solo modificaría su conjunto de prueba con un número mínimo de registros necesarios para estas pruebas en particular.

Este enfoque tiene el enorme beneficio de aprender; debido a que hay pocos archivos de datos, en el tiempo, realmente comienza a memorizarlos. En lugar de ver cientos de conjuntos de datos grandes que solo difieren en detalles imperceptibles (que debe descubrir cada vez que vuelve a realizar una prueba después de un tiempo), puede determinar con facilidad la diferencia entre dos conjuntos de datos.

Una palabra sobre el rendimiento al final. En mi 2.4 GHz 2-base de la máquina WinXP una prueba DBUnit que implica:

  • dejando caer 14 mesas,
  • la creación de 14 mesas,
  • inserción de ca. 100 registros,
  • realización de la lógica de prueba,

tarda 1-3 segundos. Los registros muestran que las primeras 3 operaciones toman menos de un segundo, la mayor parte del tiempo de prueba es consumido por Spring. Esta lógica es realizada por cada prueba, para evitar dependencias de orden de prueba. Todo se ejecuta en una máquina virtual con Derby integrado, esta es probablemente la razón por la cual es tan rápido.

EDIT: Creo que los conjuntos de datos XML DBUnit no son compatibles con la inclusión de otros archivos de prueba, se puede superar mediante el uso de una clase base para todas las pruebas de integración, por ejemplo:

public class AbstractITest { 

    @Before 
    public void setUp() throws Exception { 
     // 
     // drop and recreate tables here if needed; we use 
     // Spring's SimpleJdbcTemplate executing drop/create SQL 
     // 
     IDataSet masterDataSet = new FlatXmlDataSetBuilder().build("file://masterDataSet.xml"); 
     DatabaseOperation.CLEAN_INSERT.execute(dbUnitConnection, dataSet); 
    } 
} 

public class AbstractModuleITest extends AbstractITest { 

    @Before 
    public void setUp() throws Exception { 
     super.setUp(); 
     IDataSet moduleDataSet = new FlatXmlDataSetBuilder().build("file://moduleDataSet.xml"); 
     DatabaseOperation.CLEAN_INSERT.execute(dbUnitConnection, moduleDataSet); 
    } 
} 

public class SomeITest extends AbstractModuleITest { 
    // The "setUp()" routine only here if needed, remember to call super.setUp(). 

    @Test 
    public void someTest() { ... } 
} 
+0

Me encanta esta idea. Buscaré si dbunit admite este tipo de cosas. – egervari

+0

@egervari DBUnit Los conjuntos de datos XML probablemente no son compatibles con esto directamente; ver mi edición – MaDa

+0

Me gusta mucho tu idea. Creo que crear un conjunto de datos maestro lleno de información del diccionario es increíble. Sin embargo, no soy tan fanático de los conjuntos de datos del Módulo. Creo que es fácil agrupar las pruebas en módulos basados ​​en datos comunes hoy, pero eso puede cambiar en el futuro. Crear una dependencia de un conjunto de datos de módulos parece ser un gran dolor de cabeza si alguna vez tuvo que cambiar su diseño y no vale la pena el beneficio. Sin embargo, pude ver dónde funcionaría. Supongo que realmente depende de tu modelo de datos. – bheussler

2

La recomendación en Junit en la acción 2e no es crear demasiados conjuntos de datos (como uno por clase de prueba), sino solo lo suficiente como para mantenerlos. A excepción de unos pocos casos excepcionales, me pareció posible utilizar un conjunto de datos maestro para la mayoría de las pruebas unitarias y conjuntos de datos individuales para las pruebas de integración. Limitar el uso de ExpectedDataSets también es una opción.

Además, usé Unitils en combinación con dbunit para simplificar parte de la configuración y carga de los datos de prueba, por lo que es posible que desee considerarlos cuando corresponda.

+1

Creo que el libro está equivocado si esa es su recomendación. Cuando tiene una base de datos con 70 tablas, y tiene tantos campos booleanos diferentes en los indicadores, muchos de los criterios de búsqueda que debe probar, y así sucesivamente ... cambiar 1 fila puede causar que se rompa una gran cantidad de pruebas. Esto es malo, y creo que es una pérdida de tiempo. Tal vez el uso de un patrón de generador en el código, y luego guardarlos en la base de datos con cascadas es la respuesta. No estoy seguro. – egervari

+0

Aclaración: el uso de un único conjunto de datos maestros para la mayoría de las pruebas unitarias es lo que elegí que hago en esa situación específica. El libro solo recomienda que mantenga solo tantos conjuntos de datos como esté listo para mantener, por lo que en lugar de 1 para cada clase/tabla, puede considerar una proporción menos rigurosa. – prusswan

+0

Mi pensamiento actual es que no sería 1: 1, pero al menos el 50% de las pruebas sería 1: 1 y el resto las compartiría. A medida que mi aplicación se vuelve más y más compleja, necesito menos acoplamiento con los conjuntos de datos. Tengo 5 datasets que compilan 1 base de datos actualmente, y cada prueba usa de 1 a 5 datasets. Está diseñado para actuar como 1 base de datos. Creo que esto fue un error. Me está llevando por un camino de infierno de dependencia de prueba. – egervari

Cuestiones relacionadas