Search code examples
grailsduplicatesintegration-testingfunctional-testingfixtures

Grails fixtures plugin and functional testing duplicates data


I have a problem while running fixtureLoader.load in BootStrap.groovy.

import grails.plugin.fixtures.FixtureLoader

class BootStrap {

    def fixtureLoader

    def init = { servletContext ->

            environments {
                test  {

                    fixtureLoader.load {

                        build {
                            device1(Device, name: "device1")
                            device2(Device, name: "device2")
                            device3(Device, name: "device3")
                        }
                    }
                }
            }
        }

    def destroy = {
    }
}

When Grails starts integration test phase, the load is executed. Then when Grails starts functional test phase, the load is executed another time without cleaning previous execution.

Thats means:

If I run with "test-app functional:" or "test-app integration:" everything is all right. If I run with "test-app" both functional and integration tests are executed.

This is the JSON representation of data at functional test phase (running with "test-app"):

[[name:device3], [name:device2], [name:device1],[name:device3], [name:device2], [name:device1]]

This is same JSON representation of data at functional test phase (running with "test-app functional:")

[[name:device3], [name:device2], [name:device1]]

How to avoid this duplicates?

Thanks in advance


Solution

  • The default test database is a non-persistant in-memory hsqldb that gets discarded at the end of your tests, but changes to it will carry over between test phases. Also, integration testing rolls back changes after each test, but this doesn't apply to database changes made in Bootstrap.groovy.

    One simple way to fix this is to simple check for the existence of the fixtures before trying to create them. For example:

    environments {
        test {
            if (Device.count() == 0) {
                // build fixtures
            }
         }
     }
    

    Another possible solution is to use separate databases for integration and functional tests. There's an example of how to do it at http://www.redtoad.ca/ataylor/2011/02/setting-grails-functional-test-database/