5

I've joined a project that has a lot of files with SQL statements for creating a database that is used for integration testing.

I'm wondering how I can use these files to create a database for unit testing (using java and maven).

I can create a HSQL in-memory database for each unit test, or even use the spring jdbc embedded-database feature, but there's so many SQL statements to execute in the test setup that this is not scalable.

So I'd like to create a temporary database (that loads the SQL statements) at the start of the maven test phase, have the unit tests access this temporary database and perform various operations, then delete the temporary database at the end of the maven test phase.

I've looked at sql-maven-plugin which would allow me to do the test phase executions, but I'm not sure how to configure a temporary database that will be available across all unit tests. There's no server to connect to, and in-memory database will not work across multiple unit tests (I assume).

One option could be to use a unique temporary file, e.g. specifying the JDBC driver URL as jdbc:hsqldb:file:/path/to/temporary/file, but I'm not sure how to generate a unique temporary file in maven.

Any suggestions on how to do this, or if there's a better approach to take?

Update: I decide to use a file-based database created in target/db directory. I use the maven clean plugin to remove the target/db directory before tests are run, and the maven sql plugin to create the database from scripts.

John Q Citizen
  • 321
  • 1
  • 6
  • 15

2 Answers2

3

For this case I have created the derby-maven-plugin. It's available from Maven Central, so you don't need to add any extra repositories or anything.

You could use it like this:

    <project ...>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.carlspring.maven</groupId>
                    <artifactId>derby-maven-plugin</artifactId>
                    <version>1.8</version>
                    <configuration>
                        <basedir>${project.build.directory}/derby</basedir>
                        <port>1527</port>
                    </configuration>
                    <executions>
                        <execution>
                            <id>start-derby</id>
                            <phase>pre-integration-test</phase>
                            <goals>
                                <goal>start</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>stop-derby</id>
                            <phase>post-integration-test</phase>
                            <goals>
                                <goal>stop</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>

For more info you can also check the USAGE.

carlspring
  • 31,231
  • 29
  • 115
  • 197
0
  1. Why not create an on-disk H2 database, and have each test access it? So long as the tests don't run in parallel or interact with each other, you don't need a server.

  2. Even more so: just create memory databases in @Before and delete them in @After. Are you sure that's too slow?

  3. In pre-integration-test, you could launch an H2 (or derby) server, and shut it down in post-integration-test.

  4. You can write a maven plugin that uses session state to keep track of an embedded database service, but that's much the same as (3).

bmargulies
  • 97,814
  • 39
  • 186
  • 310
  • Thanks for the reply. Yes it is much to slow to create entire database in a @Before in each unit test. I'm not familiar with H2 or derby but will look into these. – John Q Citizen Feb 06 '13 at 14:32
  • @Benson: As mentioned on one of your other posts yesterday, as recommended in 4), I have actually created a Maven plugin for this. – carlspring Feb 26 '13 at 12:23