2009-01-20 18 views
12

Soy la creación de un servidor de integración continua (Hudson) para construir un proyecto Java y ejecutar las pruebas de la unidad/de integración pertinentes. La mayoría de estas pruebas accede a una base de datos y los datos de prueba se guardan en un archivo DbUnit XML.integración continua: mantener el esquema de base de datos de prueba hasta a la fecha

Busco una forma de mantener automáticamente el esquema de base de datos de prueba hasta al día. Actualmente la secuencia de comandos SQL para un lanzamiento en particular se almacena en un directorio llamado después de la versión de lanzamiento:

└───scripts 
    ├───0.1.0 
    ├───0.1.1 
    ├───0.1.2 
    ├───0.1.4 

Por ejemplo, la secuencia de comandos SQL para la versión 0.1.4 es

scripts\0.1.4\script-0.1.4.sql 

El problema es que estos Los scripts contienen una mezcla de cambios de esquema (por ejemplo, ALTER TABLE ...) y cambios en las tablas estáticas (por ejemplo, agregue un nuevo rol a la tabla USER_TYPE).

En el caso de las pruebas unitarias, solo quiero aplicar los cambios al esquema, porque como se mencionó anteriormente, todos los datos para las pruebas unitarias se guardan en un archivo XML DbUnit. Aunque podría separar estos dos tipos de cambios de bases de datos en diferentes archivos, a menudo habrá una dependencia entre los cambios de esquema y los cambios en los datos que deberán ser de alguna manera forzada cuando la liberación se aplica a control de calidad, producción, etc.

De todos modos, esta es solo una manera muy larga de preguntar si alguien ha presentado una forma robusta de mantener automáticamente el esquema de prueba actualizado. Sé que Unitils tiene algún soporte para mantener un esquema de prueba actualizado, pero no estoy seguro de si puede 'ignorar' las declaraciones de actualización de datos en los scripts SQL delta.

Respuesta

2

Lo que hago en mis pruebas:

  • guardo una versión DB algún lugar
  • En la primera prueba, me desgarro abajo todo el DB y construirlo desde cero
  • corro cada actualización del esquema en una prueba individual
  • corro el módulo de "actualización de base de datos" como una prueba individual (no debe hacer nada porque todos los cambios se han aplicado). Opcionalmente, derribo el DB nuevamente y lo ejecuto una vez.
  • Cargué los datos de prueba en la base de datos (algunas de las pruebas anteriores lo harán si corrigen errores de datos).

Ahora, la DB de prueba está lista para las pruebas "reales" (aplicaciones). Después de cada una de las pruebas de aplicación, retrotrajo la transacción actual para que la base de datos de prueba nunca cambie después de la instalación.

Para hacer la prueba más rápida, por lo general tienen tres conjuntos de pruebas: una que contiene la configuración de DB, uno que contiene sólo las pruebas de aplicación y una que contiene los otros dos suites. Esto me permite restablecer rápidamente el DB de prueba y ejecutar una única prueba desde el conjunto de aplicaciones.

3

Lo que hemos encontrado como la forma más manejable para gestionar la evolución gradual de vivo/prueba de DB esquemas es el uso de una herramienta de gestión de la migración de esquemas como Liquibase

Esto nos permite aplicar los últimos cambios de esquema en cualquier ambiente que así que elija, pruebe o de otra manera, de una manera consistente que luego nos permita ejecutar cualquier tipo de automatización que deseemos en comparación con el esquema actualizado.

1

utilizo migrateDB para gestionar este problema.

Esta herramienta se basa en la idea de que hay "pruebas" que puede realizar (a través de SQL) en su base de datos para ver si se ha aplicado un cambio de base de datos dado, y un conjunto correlativo de acciones para realizar una prueba " falla ". Por ejemplo, puede que necesite consultar el esquema de la metatabla para ver si existe una tabla o columna, y si no lo hace, créelo. O bien, es posible que desee ver si existe una determinada fila en una tabla, y si no, insértelo. Viene con algunas pruebas y acciones comunes preconfiguradas, y es muy fácil agregar la suya (con solo configuración XML, no necesita código nuevo para hacer esto).

Como una pequeña ventaja, cada una de estas pruebas y acciones es configurado para cada "dialecto" de SQL (por ejemplo, puede tener un dialecto "oracle" y un dialecto "mySQL"). Esto significa que una vez que define las consultas para las pruebas y acciones dadas para cada dialecto, cada instancia nueva de una prueba o acción no requiere un nuevo SQL, y puede ejecutarse contra múltiples bases de datos de destino.

Luego, solo mantiene un pequeño archivo XML que enumera las pruebas y las acciones correspondientes, y ejecuta la herramienta contra su base de datos después de cada compilación.

Funciona bastante bien para nosotros.

2

Actualmente uso un enfoque similar. He estado investigando las herramientas de migración de db y no he encontrado ninguna que resuelva el problema que describes.

El problema es que a veces un cambio de esquema requiere que se modifiquen los datos para permitir la creación de nuevas restricciones, etc. En este caso, si se ignoraron las sentencias de actualización de datos, la migración fallaría.

¿Agregaría una secuencia de comandos sql a su suite de pruebas que borra todos los datos de la base de datos?

Así que el proceso sería:

  1. plazo migración db.
  2. Ejecutar script para eliminar todos los datos en db.
  3. datos de prueba de carga
  4. ejecutar pruebas
0

Esto es lo que hacemos:

$ find src/sql/ | grep -v /.svn 
src/sql/ 
src/sql/0000-system.sql 
src/sql/0000-system.sql.dev.log 
src/sql/0000-system.sql.prod.log 
src/sql/0000-system.sql.test.log 
src/sql/0001-usgn.sql 
src/sql/0001-usgn.sql.dev.log 
src/sql/0001-usgn.sql.prod.log 
src/sql/0001-usgn.sql.test.log 
src/sql/0002-usgn.sql 
src/sql/0002-usgn.sql.dev.log 
src/sql/0002-usgn.sql.prod.log 
src/sql/0002-usgn.sql.test.log 
src/sql/0003-usgn.sql 
src/sql/0003-usgn.sql.dev.log 
src/sql/0003-usgn.sql.prod.log 
src/sql/0003-usgn.sql.test.log 
src/sql/0004-system.sql 
src/sql/0004-system.sql.dev.log 
src/sql/0005-usgn.sql 
src/sql/purge.sql 

tenemos scriptseq ### - databaseusercredential.sql

Ahora nuestras pruebas, siempre permiten para el estado de inicio desconocido de los datos en el DB. Si no puede hacer eso, le sugiero que use SEQ-CRED-TYPE.sql, donde el tipo sería dml/ddl y filtrar los scripts dml.

4

Un cartel anterior incluía a Liquibase como opción, sin embargo, no mencionaron la capacidad de Liquibase para definir reglas que se ejecutan en contextos particulares (Contexts in Liquibase). Esto le permite tener las actualizaciones de esquema no marcadas con un contexto particular y los accesorios para las pruebas unitarias marcadas como contexto de test. De esta forma, los accesorios solo se insertarán cuando ejecutes tus pruebas unitarias.

Aquí se muestra un ejemplo de un conjunto de cambios Liquibase que contiene el esquema y los accesorios:

<?xml version="1.0" encoding="UTF-8"?> 
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd"> 
    <changeSet author="avalade" id="1"> 
    <createTable tableName="users"> 
     <column autoIncrement="true" name="id" type="long"> 
     <constraints nullable="false" primaryKey="true" /> 
     </column> 
     <column name="email" type="varchar(255)" /> 
    </createTable> 
    </changeSet> 
    <changeSet author="avalade" id="2" context="test"> 
    <insert tableName="user"> 
     <column name="id" value="1" /> 
     <column name="email" value="[email protected]" /> 
    </insert> 
    </changeSet> 
</databaseChangeLog> 

Entonces, si usted está utilizando la primavera para administrar su DAO, se puede poner lo siguiente en su contexto de aplicación archivo que se va a implementar:

<bean id="liquibase" class="liquibase.spring.SpringLiquibase"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="changeLog" value="classpath:dbChangelog.xml" /> 
</bean> 

Para el archivo de contexto de aplicación que se utiliza en las pruebas unitarias, configurar Liquibase con una propiedad de contexto adicional:

<bean id="liquibase" class="liquibase.spring.SpringLiquibase"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="changeLog" value="classpath:dbChangelog.xml" /> 
    <property name="contexts" value="test" /> 
</bean> 

De esta forma, puede mantener todas las definiciones de su base de datos juntas en un solo lugar y solo insertar sus accesorios cuando está ejecutando su código de prueba.

Cuestiones relacionadas