Search code examples
grailsfunctional-programmingspockgebtest-data

How to setup and teardown functional test data in Geb grails


I have many working/passing functional geb/spock tests (each extending GebReportingSpec) that are testing a web application with test data all created from the BootStrap.groovy at the beginning of the functional test suite.

I want to move the test data creation into startup() / teardown() methods within each Spec, well actually I wanted to have them inherit it from a base class but apparently the StepWise has issues with inheritance.

So, at present each of my test spec classes look something like:

@Stepwise
class ExampleSpec extends GebReportingSpec {

    def "valid root user logs in"() {

        given: "I am at the login page"
        to LoginPage

        when: "I enter root's credentials"
        username = "root"
        password = "password"

        and: "I click the login button"
        loginButton.click()

        then: "I am logged in and directed to the welcome page"
        at WelcomePage
    }
}

Now, my problem is that I can't seem to create a new test (above the first test) that can create test data. Without having a valid given/when/then statement the test doesnt appear to be executed and calling a method from within the existing test also doesnt appear to work. I have looked into the grails-remote-control plugin to help me and I believe this will allow me to successfully envoke closures to setup data but I am not sure on the best mechanism for calling this from within the GebReportSpecs (or some abstract parent).

Below is a brief outline of the kind of thing I want to be able to do, either by making 'setupData()' the first test or by calling that method from within a test... Neither appears to work.

def remote = new RemoteControl()
def setupData() {

    def id = remote {        
        def ShiroUser user = new ShiroUser(username: "root", ...)
        user.save()
        user.id
   }
   println(id)
}

.... Tests then follow

Are there any annotations like @before etc that can force these methods to be invokved?

Any suggestions are appreciated.

Solution: I have accepted dmahapatro's response below at the correct answer, but have also provided an example of my final solution below for those who may find it useful.


Solution

  • (Untested)
    GebReportingSpec extends GebSpec which ultimately extends spock.lang.Specification which has Fixture Methods.

    You can use them like:

    @Stepwise
    class ExampleSpec extends GebReportingSpec {
        def setupSpec(){
           super.setupSpec()
           //setup your data
        }
    
        def cleanupSpec(){
           super.cleanupSpec()
           //I do not think you would need anything else here
        }
    
        def "This is test 1"(){
    
        }
    
        def "This is test 2"(){
    
        }
    }
    

    You cannot use setup as one of your test method because the sate is not maintained for a single test case. It goes like this:-

    setup called -> test1 -> teardown called  
    setup called -> test2 -> teardown called  
    setup called -> test3 -> teardown called  
    .........