Skip to content
ryanlea edited this page Apr 15, 2011 · 3 revisions

Database integration seeder is a tool used to seed databases for integration testing.

The core premise behind this tool is simplicity.

It is very much a work in progress and I welcome any and all feedback.

Background

I have used and tried to use http://dbunit.sourceforge.net/ in the past, with some success. However, the database I was using at the time was fairly complex and beyond the capabilities of dbunit. DBUnit also required my test code to be fairly polluted to carry out my simple requirement of "seed the database with some data and run a test".

I looked at extending or patching dbunit and came to the conclusion that whilst it is an excellent tool, it wasn't the tool I needed to setup my test data. Over the course of a week I cobbled together my requirements and some code that could carry out the task, which is largely what you see now.

I have since added (with some help) some minor features as well as support for Postgres and HSQL.

Usage

It has currently been used and tested on Oracle, Postgres and HSQL.

It uses spring heavily and requires the following setup in a spring.xml file:

A sample Test setup is as follows:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
    DependencyInjectionTestExecutionListener.class,
    DatabaseTestExecutionListener.class
})
@ContextConfiguration(locations = {
    "/org/dis/oracle/simple.spring.xml"
})
@DatabaseTest
public class SimpleOracleTest extends AbstractTest {

    @DatabaseTestData("/org/dis/single-table.xml")
    @Test
    public void seedIntoSingleTable() {
        ...
    }

}

@DatabaseTest

Indicates that this test class will be interacting with the database. It is currently required but does very little else.

Spring configuration

The contents of /org/dis/oracle/simple.spring.xml are:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@//127.0.0.1/xe"/>
        <property name="username" value="test"/>
        <property name="password" value="test"/>
    </bean>

    <bean id="databaseTableService"
          class="org.dis.factory.DatabaseTableServiceFactoryBean"
          p:dataSource-ref="dataSource"
         p:defaultSchema="test"/>
</beans>

Note, that the setup above is for an Oracle driver. The key bean above is the DatabaseTableServiceFactoryBean, which create a DatabaseTableService used throughout the framework.

@DatabaseTestData

Indicates that an individual test requires seed data to be initialized. Initialization uses the following workflow:

  1. Marks a flashback point in the database (Oracle only, must be configured)
  2. Reads the dataset file (discussed below)
  3. Clears each table in the dataset file, including any child dependent tables
  4. Inserts the rows in the dataset file
  5. Executes the test
  6. Flashback to the marked point (Oracle only, must be configured)

Dataset file

@DatabaseTestData takes a value that points to a resource on the classpath containing the seed data to use. This example points to the following file:

<dataset>
    <simple_table id="3" description="'description'"/>
</dataset>

The xml format is fairly loose, with the only strict requirement being that the root node is '', which is case sensitive.

Each element within a dataset represents a table name.
Each attribute name represents a column name.
Attribute values are parsed using http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html, which requires strings to be single quoted.

The file is read and executed top down.

Includes

When writing many integration tests it is common to reuse data. Common data sets can be included as a resource on the classpath. Consider the following common file in /org/dis/common/common_table.dis.xml

<dataset>
    <common_table id="1" date="new java.util.Date()"/>
</dataset>

This file can now be used as follows:

<dataset>
    <include resource="/org/dis/common/common_table.dis.xml"/>
</dataset>