Flexible H2 Database Persistence For Testing With Gradle

We talked about the database-oriented Profiles in my Spring-Data GitHub app, MySQL for production and development, H2Database for testing. On the testing side, typically an H2 Database is configured with a hbm2ddl.auto create-drop setting, to be created when the tests are run, possibly populated by a test-data.sql script, then dropped when the tests are concluded. The tests are usually configured to roll back any data created along the way.

What if, like me, sometimes you want the H2 database to hang around so you can get a visual on the records you created, updated or deleted in your tests. Sometimes I need to see user “Foo Bar” on the screen with my own eyes.

Keeping the database alive after the tests run creates a problem because next time we run the tests we still want the H2 database to be created and populated fresh. And there’s no “drop-create” hbm2ddl.auto setting.

This post covers how I added a bit of flexibility in persisting my H2 Database after tests complete and how I am creating it fresh each time my tests are run.

Creating the H2 Test Database

A few points on creating the H2 Test Database. First, our H2 datasource properties are set for “create.”

database.hbm2ddl.auto=create

The H2 Database Schema is created by the Entity Model class files on build, after which we populate the data in our H2 Spring Configuration.

@Bean
   public DatabasePopulator databasePopulator(DataSource dataSource) {
	ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
	populator.setContinueOnError(true);
	populator.setIgnoreFailedDrops(true);
	populator.addScript(new ClassPathResource("/db/h2database.sql"));
	try {
	    populator.populate(dataSource.getConnection());
	} catch (SQLException ignored) {
	}
   return populator;
}

One final piece is to create a FILE H2 database as opposed to Embedded or In-Memory.  That is also set in the H2 datasource properties file where we use “file” in the database.url property.

That creates a testdb.h2.db file in our project root, we run our tests and everything’s great! (Testdb.h2.db is highlighted in blue.)

The only problem is that the next time we run our tests they will abort out of the gate because we already have a testdb.h2 database.

Resetting the H2 Database Files After Tests

The trick is to be able to quickly remove the project H2 files on each test so they can be recreated and repopulated. This is where Gradle comes into play.

We add a Gradle task to delete our H2 Database files before our test task launches.

task rmTestdb(type: Exec) {
    commandLine "bash", "${rootDir}/doc/scripts/rmTestdb.sh"
}

The task launches a bash script which does a simple $ rm testdb.*. It may seem unnecessary to call a script here, but I did so to handle the “*” wildcard in the Gradle commandLine. The removal of prior H2 data files can’t be hard-wired into the test task, because we normally will want to use a create-drop H2 Database approach. Until that time we’ll run our tests in gradle with the following command and view our test data to our heart’s content.

$ gradle rmTestdb test

Everything shown in this post can be found on v0.1.0 of the Spring-Data app on GitHub.