Setting a Functional Test Database in Grails

So functional testing is unexpectedly easy to get running in grails. Installed the grails geb plugin, and it pretty much works out of the box. The main problem I ran into was that functional tests use the same database as integration tests. My suite of integration tests expect a pristine database and each test selectively populates it with test fixtures. Since integration test transactions get rolled back, the database stays clean.

Functional tests, on the other hand, require a real working application. Ideally, the database would be in fully populated with data representative of what’s deployed in the real world. Also, the database transactions don’t get rolled back like in the integration test phase, so test data accumulates.

Rather than trying to force the two types of tests to play nicely together, I thought it would be smarter to just use two different database instances. Even though the current test phase isn’t easily accessible, grails has a really great way to hook into the build system with events.

Capturing the Test Phase

You can capturing build events by creating a script called scripts/Events.groovy. The event we want is TestPhaseStart. Here’s an example that stuffs the current phase into a system property:

eventTestPhaseStart = { args ->
	System.properties["grails.test.phase"] = args
}

Setting the Database Dynamically

Once the test phase is in a system property, it’s easy to set the database with it. DataSource.groovy is, of course, a groovy script, so any kind of conditional logic is fine. One approach is to just embed the test phase name into the database name:

environments {
    test {
        dataSource {
            def dbName = "project-${System.properties['grails.test.phase']}"
            url = "jdbc:postgresql://localhost:5432/$dbName"
            driverClassName = "org.postgresql.Driver"
            dialect = org.hibernate.dialect.PostgreSQLDialect
            username = "testuser"
            password = "testpassword"
        }
    }
}

With this config, the functional tests will use a database called project-functional, and the integration tests will use a database called project-integration. Problem solved.

For more details on the grails event model, check out Mastering Grails: The Grails event model.

Comments are closed.