Home > Uncategorized > Grails functional testing with hudson, selenium-rc, and easyb

Grails functional testing with hudson, selenium-rc, and easyb

I recently integrated functional selenium into our build process so that we could automate the regression scripts. Most of this was straight forward as grails has plugins for selenium and easyb, but there were a couple extra steps I needed to get them working together so I thought I would share them here for those of you that are interested.

grails install-plugin selenium-rc

A basic junit test per senenium-rc documentation worked fine on my local machine. However, the continuous integration server runs linux and did not yet have firefox or X windows installed. So for starters, I needed to install xvfb and firefox. Xvfb must be running and the DISPLAY set before selenium-rc can start firefox. To do this added another build step before running grails test-app.

# start a virtual frame buffer for firefox if not already running
if [ -z "`pgrep Xvfb`" ]; then
/usr/bin/Xvfb :1 -screen 0 1024x768x24 &
fi

I also needed to install the SetEnv plugin to set the DISPLAY

DISPLAY=:1.0

If all you want is JUnit tests you should be good to go.
Easyb tests are a bit easier to read by non-developer types, so I thought I would give this a try too.

grails install-plugin easyb

This is where it got a bit tricky, the selenium plugin expects tests are placed in test/selenium rather than test/functional and although I could get them to run fine in the functional directory the selenium server wouldn’t be running. After bit of poking around in selenium-rc plugin found this:

eventTestSuiteStart = {String type ->
  if (type =~ /selenium/) {
    startSelenium()
    registerSeleniumTestListeners()
  }
}

So here the selenium server is only started if test type contains the string selenium. So to fix this I added the following to scripts/_Events.groovy to create a test type named selenium-easyb which and looks for the stories in the test/selenium folder.

eventAllTestsStart = {
  def easybTestTypeClass = loadEasybTestTypeClass()
  functionalTests << easybTestTypeClass.newInstance('selenium-easyb', 'selenium')
}

Now selenium server will be started and stopped after completion. Note however if you are using both junit and easyb the selenium server will stop and restart between them. This wasn’t an issue for me, so I didn’t concern myself with fixing it. If you have a solution please add it to the comments.

There is just one more small issue that needs solving. The selenium-rc plugin uses a groovy @Mixin to provide access to the selenium instance. I don’t think easyb supports mixins. However, if you look at the mixin source you’ll see it basically just provides an accessor to the static selenium property of SeleniumHolder so I just initialize this at the top of the script and we are good to go. My test now looks something like the following:

selenium  = grails.plugins.selenium.SeleniumHolder.selenium

import com.axion.User

scenario "A new user creates an account", {

    when "the user completes the signup form", {
        selenium.openAndWait("/wisper/")
        selenium.type("signup-firstname", "Selenium")
        selenium.type("signup-lastname", "TestUser")
        selenium.type("signup-email", "selenium@wisper.com")
        selenium.type("signup-password", "selenium")
        selenium.click("wisper-signup-button")
    }
    and "enters captcha", {
        selenium.waitForElementPresent("captcha")
        // Configuration setting used to disable captcha during testing
        selenium.type("captcha", "CAPTCHA")
        selenium.clickAndWait("confirmCaptcha")
    }
    then "a user account should have been created", {

        User.withNewSession { session ->
           user = User.findByEmail("selenium@wisper.com")
           ensure(user) {
               isNotNull
           }
       }

    }

}
after "delete user created by tests", {
    User.withNewSession {
        def user = User.findByEmail("selenium@wisper.com")
        if(user) {
            user.authorities*.removeFromPeople user
            user.profiles*.delete()
            user.delete()
        }
    }
}
About these ads
Categories: Uncategorized Tags: , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: