Tuesday, November 20, 2012

Getting started with Grails functional tests using Geb + Spock

Introduction

There are a number of different functional test frameworks that can be used with Grails. Each of which can be incorporated into the overall test infrastructure of your Grails app by including the relevant plugin:

Grails doesn't hold any opinion on which one to choose. This is fair, and gives developers choice, but it can also be a headache; one has to make the choice of which framework, and also do the necessary setup and configuration. The functional test framework of the day is currently Geb, which builds on top of another functional framework in WebDriver. Geb can be used with the test runners JUnit, TestNG, or Spock. Spock, like Geb is the tool dejour and they are commonly used together. The best thing about Spock tests is that they are easy to read.

New Dependencies in your BuildConfig

To run your functional tests you need to include a number of libraries and plugins in your BuildConfig.groovy. Here is what you typically need to merge in:
grails.project.dependency.resolution = {
  def gebVersion = "0.7.0"
  def seleniumVersion = "2.25.0"
  dependencies {
      // Geb Spock integration
      test "org.codehaus.geb:geb-spock:$gebVersion"
      // Various webdrivers to drive your tests in different browsers
      test "org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion"
      test "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion"
      test "org.seleniumhq.selenium:selenium-ie-driver:$seleniumVersion"
      test("org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion") {
        exclude 'xml-apis'
      }
  }
  plugins {
      test ":geb:0.6.3"
      test ":spock:0.6"
      // Not required, but very useful in speeding up working with functional tests
      compile ":functional-test-development:0.9.3"
      compile ":funky-test-load:0.3.9"
  }
}

Add Geb Config

Create a new file test/functional/GebConfig.groovy Add the following content:
/*
 This is the Geb configuration file.
 
 See: http://www.gebish.org/manual/current/configuration.html
*/

import org.openqa.selenium.htmlunit.HtmlUnitDriver
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.chrome.ChromeDriver

// Use htmlunit as the default
// See: http://code.google.com/p/selenium/wiki/HtmlUnitDriver
driver = { 
 def driver = new HtmlUnitDriver()
 driver.javascriptEnabled = true
 driver
}

environments {

 // run as “grails -Dgeb.env=chrome test-app”
 // See: http://code.google.com/p/selenium/wiki/ChromeDriver
 chrome {
  driver = { new ChromeDriver() }
 }

 // run as “grails -Dgeb.env=firefox test-app”
 // See: http://code.google.com/p/selenium/wiki/FirefoxDriver
 firefox {
  driver = { new FirefoxDriver() }
 }

}

Install Chrome Driver

The above listed chrome-driver library in BuildConfig is not enough to run your tests in Chrome. You also need to install on your development system an OS specific driver that acts as a bridge between what is included by the BuildConfig and the browser itself. You can find this driver here: http://code.google.com/p/selenium/wiki/ChromeDriver
  • Download, unzip the driver suitable for your development machine Place it somewhere nice I put mine in: ~/Dev/apps/chromedriver/
  • Add that folder location to your PATH export PATH=$PATH:~/Dev/apps/chromedriver

Define a Spec

The test specifications and pages are obviously going to be different for each app. I'm including a sample here, but to find out how to write specs and pages for your application consult the very comprehensive Book of Geb.
Sample Spec (test/functional/SignUpSpec.groovy):
import geb.spock.GebReportingSpec
import geb.spock.GebSpec
import spock.lang.*
import pages.*

@Stepwise
class SignUpSpec extends GebSpec {

  def "signup new customer"() {
    when:
    to SignUpFormPage, campaign: 1
    firstName = "Eamonn"
    lastName = "O'Connell"
    username = "eamonn2@stratus5.com"
    password = "x2l43j23lk4mallls"
    passwordConfirmation = "x2l43j23lk4mallls"
    orgName = "eamotest"
    addressLine1 = "GEC"
    city = "Dublin"
    signUpButton.click()

    then:
    at SignUpCompletePage 
  }

}

Sample Page (test/functional/pages/SignUpFormPage.groovy)
package pages

class SignUpFormPage extends geb.Page {

  static at = {
  heading.text() == "Sign Up"
 }
  
  static url = "signUp"

  static content = {
    firstName            { $("#firstName")                         }
    lastName             { $("#lastName")                          }
    username             { $("#username")                          }
    password             { $("input[name=password]")               }
    passwordConfirmation { $("input[name=password2]")              }
    signUpButton         { $("#submit")                            }
    orgName              { $("#orgName")                           }
    addressLine1         { $("input[name='address.addressLine1']") }
    addressLine2         { $("input[name='address.addressLine2']") }
    city                 { $("input[name='address.city']")         }
    county               { $("input[name='address.county']")       }
    zip                  { $("input[name='address.zip']")          }
    tel                  { $("#tel")                               }
  }

}
As you can see from the above defining tests using Specs and Pages is a thing of beauty.

Executing your tests

The typical way of running your grails tests is to run the test-app command like as follows:
grails test-app functional:
This works well enough, but you can find you end up waiting a lot as each test run requires the starting up of an instance of your grails app. An improvement to this process is to use the functional-test-development plugin included in the BuildConfig above. If you have included this plugin, you can run the following command:
grails develop-functional-tests
This will start up an instance of your application, and then display a console prompt with which you can run functional tests with over and over again. You can also restart the running app from the console, and there is a very handy feature where hitting the return key will run the previous test command.
grails funky-test-load
The funky test load plugin is my functional test runner of choice. It is actually inspired in part by the functional-test-development plugin. With it you can run your tests just as you would with the functional-test-development plugin, but it also enables you to also run the same test concurrently. Imagine emulating ten users signing up to your test server with a few keyboard strokes. I find it a real help in being able to reproduce troublesome concurrent issues like optimistic locking errors.

Tip: To run your test with Chrome add -Dgeb.env=chrome to the develop-functional-test console.
You can run into a few hiccups to be aware of:
  • The Grails app that runs is using the test environment, so be sure your Config.groovy is ready for that.
  • The plugin specifies memory settings for the app to run. If you have already specified memory settings in the JAVA_OPTS or GRAILS_OPTS environment variables then it will pull the memory settings from that. Otherwise it will add default ones. Now in my case, I have memory settings defined in JAVA_OPTS, and the plugin's code for parsing was not grabbing all of the settings. I had to hack the plugin a bit to get it working. It could be just how I defined the settings or it could be a bug that might well be fixed by the time you read this.

Credits

34 comments:

  1. Replies
    1. I have read your blog its very attractive and impressive. I like it your blog.

      Java Training in Chennai Core Java Training in Chennai Core Java Training in Chennai

      Java Online Training Java Online Training Core Java 8 Training in Chennai Core java 8 online training JavaEE Training in Chennai Java EE Training in Chennai

      Delete
  2. Thanks for your informative article on UFT automation testing tool. Your post helped me to understand the features and functionality of QTP automation testing tool. QTP training

    ReplyDelete
  3. This information is impressive; I am inspired with your post writing style & how continuously you describe this topic. After reading your post, thanks for taking the time to discuss this, I feel happy about it and I love learning more about this topic..
    Informatica Training in chennai | QTP Training in Chennai



    ReplyDelete
  4. new horizon security services richmond va I am really impressed with your efforts and really pleased to visit this post.

    ReplyDelete
  5. Technology place a vital part in humans ecosystem. So in order to survive one must be up to date. Thanks for sharing this information in here. Keep blogging article like this. I have bookmarked this page for future reference.


    Hadoop Training Chennai | Big Data Training| JAVA training in Chennai

    ReplyDelete
  6. Bed Bug Treatment Leesburg VA It is really a great and useful piece of information. I am glad that you shared this helpful info with us. Please keep us up to date like this. Thank you for sharing.

    ReplyDelete
  7. Really awesome blog. Your blog is really useful for me. Thanks for sharing this informative blog. Keep update your blog.
    Oracle Training In Chennai | Hadoop Training In Chennai

    ReplyDelete
  8. Best Java Training Institute In ChennaiThis information is impressive; I am inspired with your post writing style & how continuously you describe this topic. After reading your post, thanks for taking the time to discuss this, I feel happy about it and I love learning more about this topic..

    ReplyDelete
  9. residential dumpster va Galaxy Transfer is based in Northern Virginia and is a division of EnviroSolutions, Inc. GT was purchased by EnviroSolutions, Inc. in June 2013.

    ReplyDelete
  10. Excellent Post!! I am really very happy to found such helpful and fascinating post that is written in well manner. Keep posting.
    QTP Training in Chennai | Software Testing Training in Chennai | Selenium Training in Chennai

    ReplyDelete
  11. too good piece of information, I had come to know about your site from my friend sajid, bangalore,i have read atleast 7 posts of yours by now, and let me tell you, your web-page gives the best and the most interesting information. This is just the kind of information that i had been looking for, i'm already your rss reader now and i would regularly watch out for the new post, once again hats off to you! Thanks a lot once again, Regards, informatica mdm training in hyderabad,informatica training in hyderabad

    ReplyDelete
  12. Melbourne Motorcycle Accident Attorney Very interesting topic will bookmark your site to check if you write more about in the future.

    ReplyDelete
  13. We are offering high-quality Wordpress Plugins, Android IOS, Website Design And Development at most cost effective and affordable rates. Company About Us

    ReplyDelete
  14. Excellent post. Happy to visit your post. Thanks for sharing.

    web design company in chennai

    ReplyDelete
  15. Excellant content. To know the details and importance of python course visit below. Python is an object oriented high level programming language which is built in data structures combined with dynamic typing and dynamic binding making it very attractive for rapid application development.
    Python Training in Chennai | Python Course in Chennai

    ReplyDelete

  16. Really awesome blog. Your blog is really useful for me. Thanks for sharing this informative blog. Keep update your blog
    http://hadooptraininginhyderabad.co.in/salesforce-training-in-hyderabad/

    ReplyDelete
  17. what size dumpster do i need Established in 2003, EnviroSolutions is a vertically integrated solid waste collection, disposal and recycling company located in the Northeast and Mid-Atlantic regions of the United States.

    ReplyDelete
  18. Syntax:
    grails application development

    Feeling Excited After Visting Blog,Great Posting about Grails functional tests.

    ReplyDelete
  19. Rolex Watches Authentic Mens & Ladies Rolex Datejust, President Watches for Sale at JavyEstrella.com.

    ReplyDelete
  20. Thanks for Sharing the valuable information and thanks for sharing the wonderful article..We are glad to see such a wonderful article..
    QTP Training in Chennai | QTP Training Institute in Chennai | QTP Training

    ReplyDelete
  21. Thanks for Sharing the valuable information and thanks for sharing the wonderful article..We are glad to see such a wonderful article..
    sas training in chennai

    ReplyDelete
  22. Excellent post. Happy to visit your post. Thanks for sharing.

    msbi training in chennai

    ReplyDelete
  23. Great post!Thanks for sharing useful and very understanding information.
    sas training in chennai

    ReplyDelete
  24. Much obliged to you for requiring significant investment to give us a portion of the valuable and restrictive data with us.
    Regards,
    SAS Training in Chennai | SAS Course in Chennai | SAS Training Institute in Chennai

    ReplyDelete
  25. Pretty article! I found some useful information in your blog, it was awesome to read, thanks for sharing this great content to my vision, keep sharing.
    Regards,'

    QTP Training Institutes in Chennai | Selenium Training Institutes in Chennai

    ReplyDelete
  26. Well Said, you have furnished the right information that will be useful to anyone at all time. Thanks for sharing your Ideas.
    PHP Training in Chennai | PHP course in Chennai

    ReplyDelete
  27. Awesome Post! I like writing style, how you describing the topics throughout the post. I hope many web reader will keep reading your post at the end, Thanks for sharing your view.
    Regards,
    PHP Institutes in Chennai|PHP Training Center in Chennai

    ReplyDelete
  28. Good Information Eamonn O'Connell!! Really It will be more helpful for the beginners and also working professionals. I will try this and come back to you.
    Selenium training in Chennai | Best Selenium training institute in Chennai

    ReplyDelete