Why G-Func and not Webtest?

Posted by: on Jan 18, 2009 | No Comments

Some people are no doubt wondering why we have the new Grails Functional Testing plugin when we already have Webtest. There are many reasons (Webtest uses Ant to build being one of them) but for me it is primarily the differences in the DSL approach.

Webtest has an established heritage in XML-based test definition. The Grails webtest plugin is a Groovy wrapper around this grammar.

In “G-Func” the philosophy is very much that your test code should “just work” without you having to worry too much about details of the HTML pages returned. For example elements in forms are located by name OR id automatically. I have started putting together a “codex” showing how tasks are achieved in both G-Func and Webtest as a means of comparison and learning.

Another example: buttons are located by name OR id OR value – some forms still have <input type=”submit” value=”Submit”/> and we need to be able to click those in a test. We don’t need to know in the test which approach the web designer has used in the GSP. If we encode knowledge about the specific mechanism of identifying the button, we are making the test more fragile, for little benefit.

G-Func is also smart about field types in forms and “does the right thing”. Whether you’re getting or setting a hidden field, a text area, a select list, a checkbox or a radio button – the mechanism is the same, standard property assignment or method invocation:

form('form1') {
   checkbox1 = true
   checkbox2 true
   optionRadioButton = "OptionC"
   paymentMethodRadioButton "VISA"
   country = "gbr"
   destinationCountry "usa"
   firstName = "Marc"
   lastName = "Palmer"
   click "send"
}

Another strand to this is that many of the assertXXXX variants operate with “loose” comparison by default. This means that case and whitespace are all stripped out before comparing values. This makes it much easier to assert content without getting tripped up by subtle changes in whitespace or case. After all, you rarely need to know the case and whitespace is correct in some html response – its the characters that matter.

For the perfectionists, if you do need to be 100% sure, you use the assertXXXXStrict variant.

Other differences between G-Func and WebTest:

  • G-Func integrates with normal Grails testing conventions. Tests are under ./test/, so are the reports.
  • The tests are JUnit tests and use the familiar testMethod() with assertXXX calls paradigm
  • The G-Func DSL is less verbose than WebTest (see the codex). Setting/getting form fields is simple property access. What really matters is the data getting through, not what kind of field it was in!
  • The DSL, when it does use verbs, is truly specific to the domain. You use get() and post() instead of invoke(method:’GET’ …) and so on.
  • G-Func documentation is all written with direct relevance to the DSL. While WebTest is fully featured, it has documentation primarily based on the XML usage. This makes sense of course, given its heritage. However it makes the learning curve and doc lookups harder work for those working in Groovy
  • G-Func is entirely within the Grails ecosystem – it uses Gant (not Ant) and is a thing pure-Groovy layer over HtmlUnit.
  • Webtest definitely has more functionality and slightly prettier reports than G-Func at this time. However the G-Func reports are consistent with JUnit reports, and the features that users need will be incorporated into G-Func.

Anyway, I hope that clears things up for some people.

If you do have any questions, please do ask on the Grails user mailing list or get in touch with me.

Leave a Reply