tag:blogger.com,1999:blog-93908112024-03-29T07:27:32.712+00:00Ad-Hockeryad-hockery: /ad·hok'@r·ee/, n.
Gratuitous assumptions... which lead to the appearance of semi-intelligent behavior but are in fact entirely arbitrary.
[Jargon File]Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.comBlogger62125tag:blogger.com,1999:blog-9390811.post-75907527909298089222011-11-29T00:11:00.001+00:002013-02-12T07:15:10.292+00:00This blog has movedAd-Hockery is no longer updated at this location. Please redirect bookmarks to <a href="http://blog.freeside.co/">blog.freeside.co</a> for more awesome content.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com88tag:blogger.com,1999:blog-9390811.post-40718176072261544362011-11-24T00:59:00.001+00:002011-11-24T09:26:43.706+00:00Fear & loathing in functional testing land<p>As projects grow the two things I’ve repeatedly found to be particularly painful have been functional testing and data fixtures. I might write up some thoughts on data fixtures another time but what follows is a brain-dump of my troubled relationship with functional testing.</p>
<p><em>Disclaimers:</em> I have more questions than answers and I’m completely open to the idea that <em>I’m doing it all wrong</em>. I’m not trying to diss any tool or technique here. I have spent a lot of time over the last few years writing functional test coverage so I think I at least have some perspective on the issues if no clue how to solve them.</p>
<p>When I say functional testing I mean in the <a href="http://grails.org/doc/latest/guide/9.%20Testing.html#9.3%20Functional%20Testing">Grails sense of an <em>end-to-end</em> test via the browser</a>. Some people are quite resistant to writing such tests and whilst I agree that as much testing as possible should be done at as low a level as possible there are certain things that really only can be tested in that way. I’m also a big fan of the <a href="http://www.growing-object-oriented-software.com/" title="Growing Object-Oriented Software, Guided By Tests">GOOS</a> approach of working outside in; starting with a (failing) functional test that defines the desired behaviour in a user-centric way and building in to the low-level implementation with its unit tests then back out to watch the original end-to-end test (hopefully) pass.</p>
<h4 id="why_is_functional_testing_difficult">Why is functional testing difficult?</h4>
<h5 id="test_development_cadence">Test development cadence</h5>
<p>The main issue I find when constructing functional tests is what I’ll call the <em>test development cadence</em>; that is the time it takes to go round the loop (and sub-loops) of</p>
<ol>
<li>write a bit of test</li>
<li>watch it fail</li>
<li>write some code to make it work</li>
<li>watch it still fail</li>
<li>figure out if your expectation is wrong or your code doesn’t work</li>
<li>fix it</li>
<li>repeat last 3 steps <em>n</em> times</li>
<li>watch it pass</li>
<li><a href="http://s3.amazonaws.com/kym-assets/entries/icons/original/000/006/548/211092_242669842430795_4056741_n.jpg?1313963401">celebrate</a></li>
</ol>
<p>With a unit test that time is typically fast, a keystroke in an IDE and the results are available in at most a couple of seconds. Functional tests are considerably slower. Even assuming you can optimise so that the application is running and you can run the test from an IDE then Selenium has to start up a browser instance, queries execute, views need to render, etc. In the worst case you’re switching to the terminal and using <code>grails test-app functional: Blarg</code> or equivalent then waiting for the webapp to start up before the test can even start to run and shut down again before the report is generated.</p>
<p>A slow test development cadence leads to distraction (checking <em>Twitter</em>, making coffee, getting drawn into a discussion of the finer points of mixing an <em>old fashioned</em>, etc.) and distraction leads to context-switching which slows things still further.</p>
<h5 id="test_diagnostics">Test diagnostics</h5>
<p><em>GOOS</em> makes a great point about the importance of test diagnostics suggesting that the <a href="http://en.wikipedia.org/wiki/Test-driven_development" title="Test-driven development"><em>TDD</em></a> mantra of <a href="http://jamesshore.com/Blog/Red-Green-Refactor.html"><em>“red, green, refactor”</em></a> should be replaced with <em>“red, <strong>decent diagnostics</strong>, green, refactor”</em>. When a test breaks, especially one someone else wrote (or that I wrote more than a week ago and have consequently lost all recollection of), I want to be able to see what’s broken without re-running the test with added logging or resorting to a debugger. Testing further from the browser hurts diagnostics as you can’t <em>see</em> what’s not working and so have to rely solely on the quality of your assertion output. That’s not an easy thing to get right. Geb’s output when a <code>waitFor</code> condition fails is just <code>Condition did not pass in x seconds</code>. Even with direct assertions and nice <a href="http://docs.codehaus.org/display/GROOVY/Groovy+1.7+release+notes#Groovy1.7releasenotes-PowerAsserts" title="Groovy Power Asserts">power assert</a> output its not always clear whether the functionality didn’t work or the expectation is incorrect. Selenese is by no means great in this regard (a humble <code>Condition timed out</code> isn’t much help) but at least you can step back with the Selenium IDE and watch the damn thing not working much more easily.</p>
<p>Bad test diagnostics coupled with a slow test development cadence make for a horrible experience.</p>
<h4 id="the_quest_for_the_functional_testing_holy_grail">The quest for the functional testing holy grail</h4>
<p>The <em>most productive</em> I’ve ever been when writing functional tests has been when using <a href="http://seleniumhq.org/projects/ide/">Selenium IDE</a>. That’s quite an admission for someone who’s spent a considerable amount of time & energy over the last few years trying to find or build something better!</p>
<p>The test development cadence is fast. Really fast. When you’re writing tests with Selenium IDE (and I do mean <strong>write</strong> them, I’ve almost never used the recording functionality) the app is running, the browser is running and you can execute the test, a portion of the test or an individual command very quickly. You can step through the test, set breakpoints, etc. When using a framework like Grails that lets you make changes to the app without restarting you can rock along pretty rapidly.</p>
<p>That said, the downsides are not inconsiderable:</p>
<ul>
<li>Abstraction is typically poor; you’re dealing with fine details of page structure (DOM element ids, CSS selectors) and copy ‘n pasting sequences of commands that would in a sane world be defined as functions or macros. You <em>can</em> write custom JavaScript commands but with considerable limitations such as the fact that any <em>wait for x</em> step must be the last thing the command does. Lack of abstraction means lack of maintainability. As the project goes on any change in page rendering probably means picking apart a bunch of tests that fail not because the functionality they are testing has stopped working but because the implementation of that functionality has changed.</li>
<li>Atomicity is difficult. Because each test probably requires a few lines of setup it’s tempting for developers to add new assertions to an existing test. This violates the principle of having a single (logical) assertion per test. Part of the problem I think is that with Java, Groovy, Ruby, etc. each <em>file</em> can contain multiple tests whereas with Selenese each file is a single test script. The right thing to do is to have lots of small Selenese test files but it’s tempting to fall into the trap of munging tests together into the testing equivalent of a <a href="http://en.wikipedia.org/wiki/Run-on_sentence">run-on sentence</a>. One of the worst side-effects of this is that as a test suite grows it becomes really hard to identify <em>where</em> certain features are tested and to find redundancy or obsolete tests.</li>
</ul>
<p>Despite these significant failings <em>writing</em> tests in Selenium IDE is very effective. Maintaining a suite of such tests is another matter. Working on a long-running project the failings of Selenese tests start to increase logarithmically. The reason I created the <a href="http://robfletcher.github.com/grails-selenium-rc/docs/manual/index.html">Grails Selenium RC plugin</a> was to try to build something I could use in future projects that would combat the failings of Selenese. I wanted to use a ‘real’ language with selection and iteration and to be able to build a robust abstraction so that tests are not dealing with the fine details of page markup. <a href="http://www.gebish.org/">Geb</a> is another step along this road. It provides a nice way of defining page objects and modules and handles things like tracking which page class is the ‘current’ one and how and when that should change.</p>
<h4 id="what_do_i_want_from_a_functional_testing_tool_language">What do I want from a functional testing tool/language?</h4>
<p>I’m convinced that the goal of writing tests in the same language as the application is a pretty vapid one. Working inside one’s comfort zone is all very well but too many times I’ve seen things tested using Selenium or Geb that would be better tested with a unit-level JavaScript test. I’m guilty of this myself. I’m a better Groovy coder than I am a JavaScript coder so it’s easy initially to break out a new Geb spec than a new Jasmine spec. Functional testing tools are <em>really bad</em> at testing fine-grained JavaScript behaviour, though. These sort of tests are really flaky, false negatives are a fact of life. They’re wastefully slow as well. JavaScript unit tests are <em>fast</em>, faster than Groovy unit tests. As a Grails developer I’ve looked enviously at how fast tests run in Rails apps but that’s nothing compared to watching a couple of hundred <a href="http://pivotal.github.com/jasmine/">Jasmine</a> tests run in under a second. To get back to the point, I have no problem with writing my functional tests in something other than Groovy if I can hit my goals of productivity and maintainability.</p>
<p>I was at one time convinced that the ability to use loops and conditional statements in Groovy made it a more suitable testing language than Selenese but honestly, how often are such constructs really required for tests? The The single most essential thing for a maintainable suite of functional tests is the ability to create a decent abstraction. Without that you’ll be building brittle tests that fail when the implementation changes 100 times more often than they fail because the functionality they’re testing is actually broken.</p>
<h4 id="abstraction_is_key">Abstraction is key</h4>
<p>The abstraction layer needs to be powerful but simple. I’ve seen test suites crippled by badly written page object models and I’m starting to feel that the whole idea is too formalized. Building Geb content definitions with deeply nested layers of <code>Module</code> types is time consuming & difficult. With Selenium RC there’s not even the page transition logic Geb provides so you end up having to write that as well (probably getting it wrong or implementing it in several different ways in different places).</p>
<p>I can’t help thinking the page object model approach is coming at the problem from the wrong angle. Instead of abstracting the UI shouldn’t we be abstracting the behaviour? After all the goal is to have tests that describe how users interact with the application rather than how the various components that make up the application relate to one another. I’d rather have a rusty toolbox of lightweight macros and UI module definitions than a glittering palace of a page component model that I find awkward to use, extend or change. The abstraction has to be there - when I change the implementation I don’t want to spend half a day finding and fixing 100 subtly different CSS selectors scattered throughout the tests - but I don’t think it has to be particularly deep.</p>
<h4 id="where_do_i_go_from_here">Where do I go from here?</h4>
<h5 id="a_better_selenese">A better Selenese?</h5>
<p>An interesting possibility for creating better Selenese tests is the <a href="http://ttwhy.org/code/ui-doc.html">UI-Element extension library</a> that allows a UI abstraction layer to be built on top of Selenese. It also introduces the concept of <em>rollup rules</em> (paramaterized macros) that are a more powerful way of abstracting command sequences than custom Selenese commands. From what I’ve seen the tool support in Selenium IDE looks impressive too. I need an opportunity to use <em>UI-Element</em> seriously but it certainly appears promising.</p>
<p>The most impressive Selenium extension I’ve seen is Steve Cresswell’s <a href="https://github.com/energizedwork/selenium-ide-nle">Natural Language Extensions</a> that layers something like <a href="http://jbehave.org/">JBehave</a>’s feature definition language on top of Selenese. <a href="http://energizedwork.com/">Energized Work</a> used this on a couple of projects (unfortunately not ones I was involved with) and I’ve heard great stories of how it enabled really rich cooperation between developers, QA and project stakeholders. I was pleasantly surprised with how simple the underlying code appeared to be given the radical difference in the test language.</p>
<h5 id="other_options">Other options?</h5>
<p>The tools I really need to look into are:</p>
<ul>
<li><a href="http://cukes.info/">Cucumber</a> which syntactically looks like the answer to my prayers. I want to see how fast the test development cadence is. Since there’s now <a href="https://github.com/cucumber/cucumber-jvm/">a pure JVM implementation</a> I really have no excuse for not getting up to speed with it pronto.</li>
<li><a href="http://funcunit.com/">FuncUnit</a> is much lower level and I’m not sure how easy it would be to build an effective abstraction layer that kept the tests readable and maintainable but it’s fast and runs right in the browser which are potentially compelling advantages.</li>
</ul>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com161tag:blogger.com,1999:blog-9390811.post-26753087622551166332011-08-26T17:19:00.001+01:002011-08-26T17:21:07.980+01:00Grails Gotcha: Beware HEAD requests when rendering binary output in controllers<p>
Although most Grails controllers render HTML, JSON or XML output it is possible to use them to render binary data as well. We use a controller to render images uploaded by editors into our content management interface. The theory is simple enough, instead of using the <code>render</code> dynamic method or returning a <em>model</em> the controller action just writes bytes directly to the HTTP response stream. Our action looked something like this:</p>
<pre><code>def show = {
def image = Image.read(params.id)
if (image) {
response.contentType = image.contentType
response.outputStream.withStream { stream ->
stream << image.bytes
}
} else {
response.sendError SC_NOT_FOUND
}
}
</code></pre>
<p>
This seemed to work well enough. However when writing a test I noticed an odd thing. I was using <a href="http://groovy.codehaus.org/modules/http-builder/doc/rest.html">RESTClient</a> to scrape resource URLs out of and make a <em>HEAD</em> request against them to ensure the URLs were valid. Javascript and CSS files were working fine but all the non-static images in the page were getting 404s. Initially I suspected a data setup problem and spent some time ensuring my test was setting data up properly. It was only once I put some debug logging in the controller action that I saw that the controller <em>was</em> actually loading images. The 404 was not coming from the <em>else</em> block in the action as I initially assumed. I tried changing the <em>RESTClient</em> call from <em>head</em> to <em>get</em> and suddenly the image URLs started working!</p>
<p>
Once I did that I realised what the problem was. An HTTP <em>HEAD</em> request does not expect a response, in fact a server receiving a <em>HEAD</em> request <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4"><em>must not</em> return a response</a>. The response stream that our controller action is writing to is, when the request method is <em>HEAD</em>, actually a no-op stream. When the action completes Grails checks to see if anything has been committed to the response stream and since it has not assumes that we want to render a view by convention. You can probably see where this is going now. The convention is that the request gets forwarded to <code>grails-app/views/<controller>/<action>.gsp</code> which of course does not exist. The forwarded request sets a response code of <em>404</em> because there is no GSP!</p>
<p>
We caught this bug in our app completely by accident but it could actually have been quite serious. Caching proxies and CDNs may well use a <em>HEAD</em> request to revalidate content and on getting a <em>404</em> assume that the URL is no longer valid. If the <em>404</em> response itself then gets cached we could get broken images on our site because the CDN tells the client browser there's nothing there.</p>
<p>
The solution is simple enough. I changed the controller action to simply set a <em>200</em> response code when it gets a <em>HEAD</em> request for a valid image:</p>
<pre><code>def show = {
def image = Image.read(params.id)
if (image) {
if (request.method == "HEAD") {
render SC_OK
} else {
response.contentType = image.contentType
response.outputStream.withStream { stream ->
stream << image.bytes
}
}
} else {
response.sendError SC_NOT_FOUND
}
}
</code></pre>
<p>
A neater solution might be to use Grails’ support for <a href="http://grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html#6.4.5%20Mapping%20to%20HTTP%20methods">mapping actions to request methods</a> so that <em>GET</em> and <em>HEAD</em> requests dispatch to different actions.</p>
Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com64tag:blogger.com,1999:blog-9390811.post-14015103214188820642011-08-18T21:42:00.000+01:002011-08-19T10:18:47.271+01:00Data-driven variation with Spock<p>
Spock’s <code>where:</code> block is commonly used with a <a href="https://github.com/robfletcher/grails-enhanced-scaffolding/blob/master/test/projects/scaffolding-example/test/functional/scaffolding/InputTypesSpec.groovy#L18">data table</a> but can also be driven by any <code>Iterable</code> data. It’s worth bearing in mind that the data driving the <code>where:</code> block doesn’t have to be hardcoded, it can be dynamic. For example, today we implemented a spec to ensure that every table in our database schema has a primary key (because it’s required by <a href="http://ha-jdbc.sourceforge.net/">HA-JDBC</a> and not automatically added by GORM on join tables). In this spec the <code>where:</code> block is driven by the list of table names read from the database metadata.</p>
<script src="https://gist.github.com/1154459.js?file=DatabaseSchemaSpec.groovy"></script><noscript><pre><code>import grails.plugin.spock.IntegrationSpec
import java.sql.Connection
import javax.sql.DataSource
import spock.lang.*
class DatabaseSchemaSpec extends IntegrationSpec {
@Shared def dataSource
@Shared List<string> tableNames
def setupSpec() {
DataSource.mixin(DataSourceCategory)
tableNames = []
dataSource.withConnection {connection ->
def rs = connection.metaData.getTables(null, null, '%', ['TABLE'] as String[])
while (rs.next()) {
tableNames << rs.getString(3)
}
}
}
@Unroll("the #table table has a primary key")
void "all tables have a primary key"() {
expect:
dataSource.withConnection { Connection connection ->
assert connection.metaData.getPrimaryKeys(null, null, table).next()
}
where:
table << tableNames
}
}
@Category(DataSource)
class DataSourceCategory {
static void withConnection(dataSource, Closure closure) {
Connection connection = dataSource.connection
try {
closure(connection)
} finally {
connection?.close()
}
}
}</code></pre>
</noscript><p>
Something like this could be done with JUnit, of course. A test could iterate over the table names and assert that each has a primary key. However, such a test would fail fast whereas with the power of Spock’s <code>@Unroll</code> annotation the spec creates a separate test result for each database table and will run each individually regardless of whether any others pass or fail. The command line output from this spec will be enough to tell you which tables do not have primary keys as <code>@Unroll</code> puts the table name right in the test name.</p>
<p>
The other great thing about this spec is that it doesn’t require maintenance; as we add more domain classes to our app the spec will automatically check the associated tables.</p>
Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com38tag:blogger.com,1999:blog-9390811.post-47630603280827226582011-08-02T13:01:00.002+01:002011-08-02T13:05:10.050+01:00Avoiding accidental i18n in GrailsWe’re developing an app that’s exclusively for a UK audience so i18n really isn’t an issue for us. However recently we got bitten by some i18n creeping in where we didn’t want it. Specifically, when using Grails’ <code>g:dateFormat</code> tag the default behaviour is to format the date according to the <code>Locale</code> specified in the user’s <code>Accept-Language</code> header. Even though we are explicitly specifying a format pattern for the date Java is aware of localized day names for some languages so the output can vary. The result is that on a page full of English text there suddenly appears a Spanish or Swedish day name. What makes things worse is that as we use server-side content caching and a CDN if a user with a non-English <code>Accept-Language</code> header is the first to see a particular page or bit of dynamically retrieved content then the cache is primed and until it expires <em>everyone</em> will see the non-English day name text.<br />
The solution in a Grails app is as simple as replacing Spring’s standard <code>localeResolver</code> bean with an instance of <code>FixedLocaleResolver</code>. Just add the following to <em>grails-app/conf/spring/resources.groovy</em>:<br />
<pre><code>localResolver(org.springframework.web.servlet.i18n.FixedLocaleResolver, Locale.UK)</code></pre>This changes the way Spring works out the request locale and any locale-aware tags should just fall into place.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com16tag:blogger.com,1999:blog-9390811.post-74373233145190159522011-05-21T21:59:00.000+01:002011-05-21T21:59:06.667+01:00Resources plugin and modular web components for Grails apps<p>I recently gave a talk on <a href="http://www.eu2011.gr8conf.org/talk/progressive-uis">‘Building progressive UIs with Grails’</a> at <a href="http://www.eu2011.gr8conf.org/">gr8conf</a> in Copenhagen and was really pleased with the feedback & comments I received afterwards. There was a question asked at the end that I felt in retrospect I could have answered better, though. I had mentioned that the Grails <a href="http://grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html#6.7%20Ajax">AJAX tags</a> were something that should be avoided as they write script blocks directly into the page and event handlers directly onto HTML elements. I was pitching an approach based on a clean separation of clean semantic markup and script enhancements and inline script violates that separation.</p><p>I was asked if there might be any kind of tags that could be developed that provided a more appropriate replacement and answered that since modern JavaScript frameworks such as <a href="http://api.jquery.com/category/ajax/">jQuery</a> make decorating elements with AJAX functionality so easy that I didn’t think there was much point.</p><p>I wouldn’t want anyone to understand me to mean that creating taglibs and GSP templates for modular components of your pages is a bad thing. I’d just advocate keeping the script out of them. Custom tags that write out markup or delegate to templates can be really useful for building complex reusable modules. Pairing those with external JavaScript files that enhance the generated markup would be very effective.</p><p>If you’re using the <a href="http://grails.org/plugin/resources">resources plugin</a> (and really… you should be) then there’s a really neat way to tie the taglib or template to the JavaScript file as well. I did briefly mention this in my talk but it’s worth expanding on here as it’s a technique with a lot of potential.</p><p>The resources plugin’s <code>r:use</code> tag doesn’t write out anything directly to the page but rather adds a resource module to a list that will get written out at the appropriate place in the page when the <code>r:layoutResources</code> tag is used. This means modular components throughout the page can declare a dependency on JavaScript and CSS resources by simply calling <code>r:use</code>. In a complex app this can be a real boon as it might not be obvious from the top level GSP exactly which modules are going to get rendered. Also if a module is later added to or removed from a page you don’t need to worry about fiddling around with resource declarations in the top level GSP. Taglibs or templates become real drop in components whilst maintaining a nice clean separation of markup and script. Even better, if you use the same resource dependency multiple times the plugin ensures the resources are actually only linked once.</p><p>Since <code>r:layoutResources</code> is typically used in a SiteMesh layout the resources your module depends on can even be ones that need to appear in the <code>head</code> of the document. The SiteMesh is rendered after the GSP it decorates so any <code>r:use</code> calls will already have been made.</p>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com20tag:blogger.com,1999:blog-9390811.post-65079817280892117842011-03-26T16:25:00.008+00:002011-03-26T16:39:41.622+00:00CSS box model hacking<p>Want to make an HTML element fill 100% of its parent’s width but also give it a border and/or some padding? Since the width of an element is <em>exclusive</em> of its border and padding this can be a pain. However there’s a fairly simple CSS solution that works cross-browser.</p>
<p>Here’s an example. Both input boxes are set to <code>width: 100%</code> and have <code>padding: 5px</code>. The first input shows the problem. Because the padding and border are added to the width of the element it overflows its container. The box model of the second input has been modified so that the padding and border are <em>inside</em> the declared width.</p>
<style>
#example {
border-style: dotted;
background: #ccc;
margin: 0 auto;
padding: 5px;
width: 300px;
}
#example, #example input {
border-color: #444;
border-width: 1px;
}
#example input {
border-style: solid;
}
#example label {
cursor: pointer;
display: block;
}
#example input {
padding: 5px;
width: 100%;
}
#example #example-2 {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
</style>
<fieldset id="example">
<label for="example-1">Field 1</label>
<input id="example-1">
<label for="example-2">Field 2</label>
<input id="example-2">
</fieldset>
<p>The trick to modifying the box model is to set <code>box-sizing: border-box</code>. Unfortunately that’s not a cross-browser property, only Opera supports it at the moment. To get the same effect in other browsers you will also need to set browser-specific versions as well:</p>
<pre><code> -moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
</code></pre>
Note that Internet Explorer only supports the <code>-ms-box-sizing</code> property from version 8 upwards so you should probably be judicious with this technique or use an alternative method to get a similar effect in IE7 and below.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com38tag:blogger.com,1999:blog-9390811.post-91721299709372193612011-03-25T00:10:00.001+00:002011-03-26T17:54:06.768+00:00Styling with HTML5 form validation<p>HTML5 specifies a number of enhancements to form inputs that are gradually being implemented by newer browsers. Among the enhancements is support for some level of automatic form validation. When inputs have invalid values the browser may refuse to submit the form. Currently Opera, Safari, Chrome and Firefox 4 have some support for this. IE8 does not. I haven’t experimented with IE9 yet.</p><p>Let’s look at <a href="http://inputvalidation.s3-website-us-east-1.amazonaws.com/">an example</a>. A simple registration form has inputs for the <em>name</em>, <em>email</em> and <em>website</em> of a prospective user. Of these <em>name</em> and <em>email</em> are required. The input elements are as follows:</p><pre><code><input type="text" name="name" required>
<input type="email" name="email" required>
<input type="url" name="website">
</code></pre><p>The <code>required</code> attribute is new in HTML5 as are the input types <code>email</code> and <code>url</code>. All of these have implications for validation. Additionally the new input types, whilst they appear just like regular text inputs in desktop browsers are great for mobile users as they are given optimised virtual keyboard layouts.</p><p>CSS3 has <code>:invalid</code>, <code>:required</code> and <code>:optional</code> pseudo-classes that are supported by current versions of Firefox, Chrome, Safari and Opera. Some browsers also refuse to submit the form if a <code>required</code> field is not filled in or invalid values are entered in <code>url</code> or <code>email</code> type fields. Obviously without appropriate feedback this could be a pretty disastrous user experience and thankfully even the Webkit browsers which until recently were blocking form submission without feedback are now handling things better.</p><ul>
<li><em>Firefox 4</em>, <em>Opera 11.01</em> and <em>Chrome 10.0.648.204</em> all block form submission if there is an empty <code>required</code> field or invalid value and display a message next to the first such field.</li>
<li><em>Safari 5.0.4</em> will apply <code>:invalid</code> CSS rules but allows the form to be submitted.</li>
</ul><p>Applying styles to invalid fields is pretty easy. For example to highlight invalid fields with a red border and background:</p><pre><code>input {
border: 1px solid #ccc;
}
input:invalid {
background: #fff3f3;
border-color: #f66;
}
</code></pre><p>You can also combine the <code>:invalid</code> pseudo-class in combination with others. For example to highlight focused fields with a fancy CSS3 box-shadow:</p><pre><code>input:focus {
border-color: #99f;
outline: none;
-moz-box-shadow: 0 0 0.25em #99f;
-webkit-box-shadow: 0 0 0.25em #99f;
box-shadow: 0 0 0.25em #99f;
}
input:focus:invalid {
-moz-box-shadow: 0 0 0.25em #f66;
-webkit-box-shadow: 0 0 0.25em #f66;
box-shadow: 0 0 0.25em #f66;
}
</code></pre><p>It’s worth noting that Firefox 4 automatically adds a red box-shadow to invalid fields (and not just focused ones). To turn it off you can specify:</p><pre><code>input:invalid {
-moz-box-shadow: none;
}
</code></pre><p>Of course, the browsers that display messages when they refuse to submit a form do so with different text and different visual effects so creating a consistent cross-browser look and feel with both client and server side validation messages is going to be an interesting challenge.</p>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com26tag:blogger.com,1999:blog-9390811.post-82371105040618739412011-03-06T20:08:00.001+00:002011-03-06T20:10:00.150+00:00Date and time inputs vs. usability<p>Form input controls for date/time values have always been problematic. The more I experiment with different options, the more I think there is no one-size-fits-all solution.</p><h2 id="calendar_widgets">Calendar widgets</h2><p>Calendar widgets such as the <a href="http://jqueryui.com/demos/datepicker/">jQuery UI date picker</a> or the <a href="http://dev.opera.com/articles/view/new-form-features-in-html5/#input-datetime" title="<input type="date"> and other date/time controls at Dev.Opera">Opera HTML5 date input</a> are very popular and can be a slick looking addition to a form. I don’t think they’re entirely positive though and certainly don’t work in all situations. They’re great when you don’t know exactly the date you want (<em>I want to book a flight around Easter time</em>) or you need to have an overview of the calendar (<em>I need to set a reminder for <a href="http://twitter.com/#!/LondonGGUG" title="London Groovy & Grails User Group on Twitter">GGUG</a> on the third Tuesday of every month</em>). However, when trying to enter your date of birth the widget is just in the way. Even if the widget is keyboard accessible and doesn’t force you to page month-by-month to the correct year you can almost certainly type the date quicker than you can find and select it in a calendar widget.</p><h2 id="multi_field_inputs">Multi-field inputs</h2><p>A multi-field input works well for entering familiar dates such as your date of birth or for transcribing data. They’re not so good when you need the context a calendar widget affords (please don’t force your users to mentally calculate what date the 3rd Tuesday of next month is).</p><p>With a multi-field input it’s vital to remember that users in different places will expect to enter dates in a different order. For example, here in the UK we use the completely logical <em>dd mm yyyy</em> order whilst an American will, bizarrely, want to put the month before the day. It’s not particularly difficult to build a tag that renders the fields in a different order according to the request locale. Using <a href="http://diveintohtml5.org/forms.html#placeholder" title="Placeholder Text at Dive Into HTML5">the HTML5 <em>placeholder</em> attribute</a> (or a suitable fallback for older browsers) is invaluable to ensure that users know which field is which.</p><p>A possible optimisation is to auto-tab between fields after the user has typed the requisite number of digits. In that case you should allow for the user to correct mistakes, so backspacing or using the cursor keys should also automatically jump between fields otherwise the auto-tabbing behaviour becomes more a hinderance than a help for fat-fingered typists like me.</p><h2 id="selects_in_a_multi_field_input">Selects in a multi-field input</h2><p>It’s very common to use a <code>select</code> input for some or all portions of the date. Personally, I pretty much detest this practice as it combines all the inconvenience of a calendar widget with none of the contextual information. <a href="http://grails.org/doc/latest/ref/Tags/datePicker.html" title="datePicker tag in the Grails user guide">Grails’ <g:datePicker> tag</a> does exactly this. Not only are <code>select</code> elements like this bulking out the page with huge option lists (Grails’ datePicker dumps 8.6Kb of markup in your page <em>without</em> time fields!) but they are cumbersome to input values into with the keyboard because so many values start with the same character. An arguable exception is a <code>select</code> for the month field as presenting textual values rather than numbers is a little friendlier and the option list is short enough and the values distinct enough to allow for reasonably quick keyboard selection.</p><p>I suspect the rationale for using <code>select</code> elements is often that it all but ensures the user can’t enter an invalid value (I’ve even seen significant hoop-jumping done in Javascript to ensure values such as <em>30th February</em> can’t be entered). I think it’s preferable to give the user a clear input and trust them to do the right thing with it rather than forcing them to use an awkward input so that they <em>can’t</em> get it wrong.</p><h2 id="simple_textual_inputs">Simple textual inputs</h2><p>You shouldn’t rule out using just a basic text input. In fact for monotonous data entry purposes it is probably optimal. The keystrokes to enter a date become muscle memory and there’s no fiddling about tabbing between day, month and year fields or grabbing the mouse to pick options from a select element. Obviously the down-side is that a plain text input is error-prone and very liable to confuse users unless the expected format is made clear.</p><h2 id="html5">HTML5</h2><p>HTML5 specifies <a href="http://diveintohtml5.org/forms.html#type-date" title="Date Pickers at Dive Into HTML5">various new date and time input types</a> which seems like good news but has some significant drawbacks at the moment. I can only imagine the new input types are designed to be rendered as native browser widgets (currently only Opera actually does so) as the required format is just about the most inconvenient imaginable for text entry. Sure, as a developer it’s appealing to require that dates have to be entered as <code>yyyy-mm-dd</code> as you no longer have to support varied input formats but no user in the world would naturally type a date that way. Therefore, to make such inputs usable you really need to use Javascript to proxy them with a widget or a set of multi-field inputs. Fine, but what about users who disable Javascript or use mobile or assistive devices that might not cope particularly well with the widgets? The fallback - a text input into which the user must type a <a href="http://tools.ietf.org/html/rfc3339#section-5.8" title="Examples of RFC3339 date values">machine-readable RFC3339 date</a> - is pretty unfriendly.</p><p>What’s worse is that Webkit based browsers such as Chrome and Safari will render the new input types as regular text inputs but refuse to submit a form containing incorrectly formatted values and unbelievably provide no user feedback whatsoever when they do so.</p><p>I’m inclined to think that the useful support for the new input types is so minimal and the actively user-hostile handling of them so much more widespread that they’re best avoided altogether.</p><p>So, to sum up:</p><ul><li>Think about who your users are and what they are trying to accomplish with <em>this particular</em> input field and give them the right input for the job at hand.</li><li>If they need to type some or all of the value make sure it’s clear what format is expected or which field is which.</li><li>Allow for people to enter values in the order they are comfortable with and above all <em>don’t</em> force them to type it in a machine-readable format.</li><li>Don’t strand Chrome and Safari users with broken HTML5 input types.</li></ul>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com185tag:blogger.com,1999:blog-9390811.post-85974277973601629672011-02-22T22:31:00.000+00:002011-02-22T22:31:06.869+00:00JavaScript's history object, pushState and the back button<p>I’m not sure if it’s the immaturity of the browser support or my general uselessness but I’ve been having some trouble with the JavaScript <em>history</em> API.</p><p>I won’t try to explain the <em>history</em> API here, it’s pretty well covered at <a href="https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history" title=""Manipulating the browser history" at Mozilla Developer Network">Mozilla Developer Network</a> and <a href="http://dev.w3.org/html5/spec-author-view/history.html" title=""Session history and navigation" at HTML5 Edition for Web Authors">W3</a>. The basics are simple enough:</p><ul>
<li>The API provides two methods; <a href="http://dev.w3.org/html5/spec/history.html#dom-history-pushstate"><code>pushState</code></a> which allows you to add a new entry to the browser history and <a href="http://dev.w3.org/html5/spec/history.html#dom-history-replacestate"><code>replaceState</code></a> which modifies the current history entry.</li>
<li>New entries added to history using <code>pushState</code> can be navigated via the browser’s <em>back</em> and <em>forward</em> buttons and a <code>popstate</code> event is fired on the <code>window</code> object when this happens.</li>
<li>Both methods allow you to attach arbitrary data to the history entry that you can use to reconstruct the appropriate page state when the user uses the <em>back</em> or <em>forward</em> buttons.</li>
</ul><p>I imagine a pretty typical use-case is what I’ve been trying to do with the pagination and sorting on the list pages of <em>Grails</em> scaffolding. Instead of pagination links and column headers causing a full page reload when clicked I intercept the click event and send an AJAX request getting back a page fragment I can use to update the list in the page. Easy enough, however without the <em>history</em> API it will break the back and forward buttons and make deep linking impossible. This isn’t an acceptable option so in true <a href="http://en.wikipedia.org/wiki/Progressive_enhancement" title=""Progressive enhancement" at Wikipedia">progressive enhancement</a> style I’ve used <a href="http://www.modernizr.com/" title="Modernizr JavaScript library">Modernizr</a> and only apply the AJAX behaviour if the browser supports the <em>history</em> API.</p><p>The essence of the script involved is this:</p><pre><code>var links = //... pagination and sorting links
var container = //... the region of the page that will be updated with AJAX
// override clicks on the links
links.live('click', function() {
// grab the link's URL
var url = $(this).attr('href');
// add a new history entry
history.pushState({ path: url }, '', url);
// load the page fragment into the container with AJAX
container.load(url);
// prevent the link click bubbling
return false;
});
// handle the back and forward buttons
$(window).bind('popstate', function(event) {
// if the event has our history data on it, load the page fragment with AJAX
var state = event.originalEvent.state;
if (state) {
container.load(state.path);
}
});
// when the page first loads update the history entry with the URL
// needed to recreate the 'first' page with AJAX
history.replaceState({ path: window.location.href }, '');
</code></pre><p>At first glance this works pretty nicely. In browsers that support <em>history</em> (right now that’s just Chrome, Safari and its mobile variants) paginating and sorting the list does not refresh the entire page but the browser’s location bar <em>is</em> updated so copy-pasting or bookmarking the URL will give a valid link to the current page. What’s more, the back and forward buttons can be used to step back through the list pages just as if we reloaded the whole page. In non-<em>history</em>-compliant browsers the list page behaves just like it always did; the links reload the entire page.</p><p>Unfortunately there’s a problem that was <a href="https://github.com/robfletcher/grails-scaffolding/issues#issue/2">reported to me on GitHub</a> shortly after I uploaded a demo of my scaffolding work. Where everything falls down is when you paginate the list, follow a link off the page (or just use a bookmark or type in a URL), then use the <em>back</em> button to return to it. In Chrome and iPad/iPhone variants of Safari the browser displays just the page fragment from the last AJAX call, losing all the surrounding page along with styling, scripts, etc.</p><p>Where things get very odd is that adding a <code>Cache-Control: no-cache</code> header to the AJAX responses makes the problem disappear, presumably because the browser then doesn’t cache the AJAX response and has to use the historical URL to reload the entire page. Remember, in good progressive enhancement style the URL for the full page or the fragment is the same. The server uses the <code>X-Requested-With</code> header to decide whether to return a fragment or the whole page. Obviously, forgoing caching is hardly an acceptable compromise but it’s interesting in that it reveals what the browser is doing. It can’t, surely, be right for the browser to treat a page fragment the same as a full document!</p><p>Curiously in <em>desktop</em> Safari this doesn’t happen and the full page is loaded as you would hope. Looking at the <em>User-Agent</em> header it looks like Safari is using an older version of WebKit (<em>533.19.4</em> rather than <em>534.13</em>).</p><p>You can see the behaviour in my <a href="http://scaffolding.elasticbeanstalk.com/" title="Grails Scaffolding sample app">scaffolding sample app</a>. I also ran into the exact same issue today at work whilst trying to add history navigation to <a href="http://skyliving.sky.com/celebrity/find-a-celebrity" title="Celebrity Finder on Sky Living">this page</a> (which is a good example of why you’d want to use <em>history</em> in the first place). I don’t think it’s just me, either. The same problem can be seen with the demo linked from <a href="http://js-html5.com/post/3014620142/history-api" title=""Using the History API" at JavaScript in HTML5">this post</a> about the <em>history</em> API.</p><p>If there are any JavaScript experts out there who can point out my obvious incompetence here, that would be great. Otherwise I guess I’ll have to wait for updates to WebKit to hopefully fix the issue before I can start applying this technique with confidence.</p>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com290tag:blogger.com,1999:blog-9390811.post-84534808229123773012011-02-06T15:02:00.002+00:002011-02-06T15:08:36.307+00:00Running Geb tests from your IDE<p>A frequent complaint about functional testing in Grails is that the start up / shut down cycle time of the app makes prototyping a functional test prohibitive. There has been some recent progress in this are with Luke Daley's <a href="http://www.grails.org/plugin/functional-test-development">Functional test development plugin</a> but it would be really nice to be able to just run functional tests from inside your IDE in the same way as a similar unit test.</p><p>With Geb and IntelliJ Idea at least this is actually pretty straightforward (I'm sure the same thing is possible with Eclipse/STS I'm just not familiar enough with it).</p><p>Geb's dependence on the Grails lifecycle is pretty minimal so the tests can run without needing any magic to happen in any <em>_Events</em> scripts (unlike the Selenium RC plugin where this would be significantly more difficult). One extra step <em>is</em> required; the Grails Geb plugin normally picks up its base URL from Grails configuration and the test will not be running in the same JVM as the Grails app if it runs from the IDE so configuration will not be available. Just add the following method to your test that extends <em>GebTests</em> or <em>GebSpec</em> (or add it to a base class):<pre><code>@Override String getBaseUrl() {
super.baseUrl ?: "http://localhost:8080"
}</code></pre>Now Geb will use the Grails configured base URL if it <em>is</em> in the same JVM as the app or default to <code>http://localhost:8080</code> otherwise (obviously you need to change that default if that's not the host or port where your app runs).</p><p>You can then just run up the app from the command line, open the test in IntelliJ and hit <kbd>Ctrl + Shift + F10</kbd> to run it. When the test completes the app is still running so you can make changes & run again with minimal turnaround time. Since the app is running in development mode you can make application changes without a server restart as well.</p><p>
IntelliJ Idea's test integration is pretty good and it even groks Spock specifications. You can also debug and step through the test. The only downside is that you can't directly access domain classes or other application components in the test as they are only available from the app's JVM.</p>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com37tag:blogger.com,1999:blog-9390811.post-29708679502349949072010-11-30T13:47:00.001+00:002010-11-30T14:04:27.665+00:00Encapsulating page state and actions in Geb<p>Geb <em>Page</em> and <em>Module</em> classes are just regular Groovy classes. In addition to the <em>content</em> DSL you can declare methods just as you would in any other class. Those methods can use content properties directly. This is really useful for encapsulating state and actions in a reusable way.</p>
<p>In this post I want to run through a couple of simple examples of re-usable <em>Module</em> classes that are enhanced with methods. Although the examples deal with <em>Module</em> classes everything here is equally applicable to <em>Page</em> classes.</p>
<p>Page object methods tend to fall into two categories:</p>
<dt>Observers</dt>
<dd>report on some aspect of page state (e.g. whether a user is logged in or not).</dd>
<dd>have non-<em>void</em> return types (I prefer explicit return types on methods but <code>def</code> would work too).</dd>
<dd>can be used for making assertions.</dd>
<dt>Actions</dt>
<dd>perform an action such as clicking a link or button.</dd>
<dd>will typically be <em>void</em> (note that it's not necessary to return a <em>Page</em> instance or class from a navigation method in <em>Geb</em>).</dd>
<dd>throw <em>IllegalStateException</em> if the action is invalid in the current page state.</dd>
<p>First let's consider an authentication module that can be used across every page in a site. The markup of the module can be completely different depending on whether a user is logged in or not. When not logged in a username/password form is shown:</p>
<pre><code><aside id="auth">
<fieldset>
<legend>Log In</legend>
<form action="/auth/login" method="post" >
<label>Username: <input name="username"/></label>
<label>Password: <input type="password" name="password"></label>
<button name="login" type="submit">Log In</button>
</form>
</fieldset>
</aside>
</code></pre>
<p>When logged in, a welcome message is shown:</p>
<pre><code><aside id="auth">
Welcome back <span class="username">blackbeard</span>
<a href="/auth/logout" name="logout">Log Out</a>
</aside>
</code></pre>
<p>To model this I'll create a Geb <em>Module</em> like this:</p>
<pre><code>class AuthModule extends Module {
static base = { $("aside#auth") }
static content = {
username(required: false) { $(".username").text() }
logoutButton(required: false, to: HomePage) { $("a[name=logout]") }
form(required: false) { $("form") }
loginButton(required: false, to: HomePage) { $("button[name=login]") }
}
}
</code></pre>
<p>The <code>required: false</code> declaration is used to declare content properties that may or may not be on the page. The <code>username</code> and <code>logoutButton</code> properties are only present in the logged-in state and the <code>form</code> and <code>loginButton</code> properties are only present in the logged-out state.</p>
<p>I can use the module in some tests like this:</p>
<pre><code>def "user can log in"() {
when:
authModule.form.username = "blackbeard"
authModule.form.password = "yohoho!"
authModule.loginButton.click()
then:
at HomePage
authModule.username == "blackbeard"
}
def "user can log out"() {
when:
authModule.logoutButton.click()
then:
at HomePage
authModule.username == null
}
</code></pre>
<p>This is a good start but there are several assumptions and bits of page detail creeping into the test. The test is using the presence or absence of the <em>username</em> to determine if someone is logged in or not. That doesn't lead to a very meaningful assertion in the test and is assuming things about the page detail. Likewise the login step is quite long-winded and likely to be repeated in a lot of tests. Not only that but it won't work if a user is already logged in as the form fields won't be present on the page.</p>
<p>To encapsulate the module's state and actions better I'll add the following methods:</p>
<pre><code>boolean isLoggedIn() { username }
void login(String username, String password = "password") {
if (loggedIn) throw new IllegalStateException("already logged in")
form.username = username
form.password = password
loginButton.click()
}
void logout() {
if (!loggedIn) throw new IllegalStateException("already logged out")
logoutButton.click()
}
</code></pre>
<p>The methods declared by the module abstract some detail away very effectively. The <code>isLoggedIn</code> method means I can change the login detection mechanism later and just change the module's method rather than a bunch of tests. The <code>login</code> and <code>logout</code> methods abstract away the <em>how</em> of logging in and out so the test can just deal with the <em>what</em>. I've used <em>IllegalStateException</em> for cases where a method is called when the module is not in the correct state. The tests now look much clearer:</p>
<pre><code>def "user can log in"() {
when:
authModule.login "blackbeard"
then:
at HomePage
authModule.username == "blackbeard"
}
def "user can log out"() {
when:
authModule.logout()
then:
at HomePage
!authModule.loggedIn
}
</code></pre>
<p>Another good example of encapsulating state and behaviour like this is a typical pagination module that would appear on a list or search results page. The markup would look something like this (I've omitted the link <code>href</code> attributes for clarity):</p>
<pre><code><nav class="pagination">
<a class="prevLink">Previous</a>
<a class="step">1</a>
<span class="currentStep">2</span>
<a class="step">3</a>
<a class="nextLink">Next</a>
</nav>
</code></pre>
<p>The <em>previous</em> and <em>next</em> links will only appear when there is a previous or next page and no links will be present at all if there is only a single page. The following <em>Module</em> class models the state and actions of this component:</p>
<pre><code>class Pagination extends Module {
static content = {
links(required: false) { $("a") }
currentPage(required: false) { $(".currentStep")?.text()?.toInteger() ?: 1 }
nextLink(required: false) { links.filter(".nextLink") }
previousLink(required: false) { links.filter(".prevLink") }
}
boolean isFirstPage() {
previousLink.empty
}
boolean isLastPage() {
nextLink.empty
}
void toPage(int pageNumber) {
def link = links.filter(text: "$pageNumber")
if (!link) throw new IllegalArgumentException("Page number $pageNumber not present in pagination")
link.click()
}
void nextPage() {
if (lastPage) throw new IllegalStateException("Already on the last page")
nextLink.click()
}
void previousPage() {
if (firstPage) throw new IllegalStateException("Already on the first page")
previousLink.click()
}
}
</code></pre>
<p>Breaking the <em>Module</em> down in detail:</p>
<ul>
<li>The <code>currentPage</code> property returns the current page number as an <code>int</code> and defaults to <code>1</code> if there is no pagination present in the page.</li>
<li>The <code>isFirstPage</code> and <code>isLastPage</code> observer methods use the absence of the previous and next links respectively to determine if the current page is the first or last one.</li>
<li>The <code>toPage</code> method finds a numbered link and clicks it, throwing <em>IllegalArgumentException</em> if no such link is present.</li>
<li>The <code>nextPage</code> and <code>previousPage</code> action methods throw <em>IllegalStateException</em> if the relevant link is not on the page.</li>
</ul>
<p>The <em>Pagination</em> class now neatly encapsulates the detail of the pagination elements and presents a higher-level façade to the tests.</p>
<p>Fuller versions of the examples in this post can be found <a href="https://github.com/robfletcher/geb-examples" title="geb-examples project on GitHub">on GitHub</a>.</p>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com8tag:blogger.com,1999:blog-9390811.post-38207504651450037232010-11-26T00:17:00.001+00:002010-11-26T00:18:43.811+00:00Modelling repeating structures with Geb page objects<p><a href="http://geb.codehaus.org/" title="Geb">Geb</a> is the hot new thing in Grails functional testing. One of its most powerful features is the concise DSL for defining page objects. The reasons for using page objects are <a href="http://code.google.com/p/selenium/wiki/PageObjects" title="Page Objects">well</a> <a href="http://robfletcher.github.com/grails-selenium-rc/docs/manual/guide/4.%20Using%20Page%20Objects.html" title="Using Page Objects">enumerated</a> <a href="http://geb.codehaus.org/manual/latest/pages.html#the_page_object_pattern_why" title="The Page Object Pattern - why?">elsewhere</a> but the basic point is to allow your tests to interact with pages in a manner agnostic of the detail of their structure. This is both practical (you can change markup structure without having to fix numerous tests that only fail because they were tightly coupled to that structure) and aesthetic (your tests read more like a user’s interaction with the page - the <em>what</em> rather than the <em>how</em>).</p>
<p>I want to put together a few short blog posts dealing with patterns that I find useful for defining page objects and modules in Geb. As I go I’ll keep adding to a very simple Grails project showing working examples which is <a href="https://github.com/robfletcher/geb-examples/">available on GitHub</a>.</p>
<p>In this post I want to talk about repeating data structures such as lists and tables and how to model them effectively.</p>
<p>A <em>content</em> property in a Geb <code>Page</code> or <code>Module</code> can be any type; whatever is returned from the defining closure. This will frequently be a Geb <code>Navigator</code> instance or a <code>String</code> but can be whatever is useful for the tests you’re writing. A good rule of thumb is that the test should be dealing with as simplified a view of the data as possible. All the complexity of traversing HTML elements and manipulating them into a useful form should be hidden away in the page objects and modules. When handling repeating data structures such as <code>ol</code> or <code>table</code> elements you probably want to be able to treat the content as a <code>List</code> so that tests can use Groovy features such as iterator methods, indexing and slicing to make very expressive assertions.</p>
<h3 id="simple_repeating_structures">Simple repeating structures</h3>
<p>For example, imagine we want to verify an <code>ol</code> element like this:</p>
<pre><code><ol id="recent-books">
<li>Zero History</li>
<li>Surface Detail</li>
<li>The Machine of Death</li>
</ol>
</code></pre>
<p>The most useful type would probably be a <code>List<String></code> which we can get easily enough by defining our content like this:</p>
<pre><code>static content = {
recentBooks { $("ol#recent-books li")*.text() }
}
</code></pre>
<p>This is then very easy to use in a test:</p>
<pre><code>expect:
recentBooks == ["Zero History", "Surface Detail", "The Machine of Death"]
</code></pre>
<h3 id="complex_repeating_structures_using_modules">Complex repeating structures using Modules</h3>
<p>A more complex example of a repeating structure is a table, where each row contains several fields. Here we can use a Geb <code>Module</code> to represent each row, with content properties to get data from each cell. Let’s say we want to verify the contents of the following table of search results:</p>
<pre><code><table id="book-results">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Format</th>
<th>Price</th>
<th>Release Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>Zero History</td>
<td>William Gibson</td>
<td>Hardback</td>
<td>£12.29</td>
<td>2 Sep 2010</td>
</tr>
<tr>
<td>Zero History</td>
<td>William Gibson</td>
<td>Kindle</td>
<td>£11.99</td>
<td>2 Sep 2010</td>
</tr>
<tr>
<td>Spook Country</td>
<td>William Gibson</td>
<td>Paperback</td>
<td>£5.00</td>
<td>31 Jul 2008</td>
</tr>
<tr>
<td>Pattern Recognition</td>
<td>William Gibson</td>
<td>Paperback</td>
<td>£4.99</td>
<td>24 Jun 2004</td>
</tr>
</tbody>
</table>
</code></pre>
<p>We can define our module like this:</p>
<pre><code>static content = {
bookResults { i -> module BookRow, $("table#book-results tbody tr", i) }
}
class BookRow extends Module {
static content = {
cell { i -> $("td", i) }
title { cell(0).text() }
author { cell(1).text() }
format { cell(2).text() }
price { cell(3).text()[1..-1].toDouble() }
releaseDate { cell(4).text() }
}
}
</code></pre>
<p>The <code>bookResults</code> content closure takes a row number parameter and uses it to select the corresponding <code>tr</code> from the body of the table and use that to construct a module. The module itself defines content properties with meaningful names that map to the text in each cell.</p>
<p>This isn’t bad as far as it goes. We can use the module pretty effectively in tests like this:</p>
<pre><code>expect:
bookResults(0).title == "Zero History"
bookResults(3).price == 4.99
</code></pre>
<p>However, <code>bookResults</code> isn’t a <code>List</code>. We can’t easily get all the book titles at once or make an assertion that all the authors are the same or find the lowest price. Even querying how many rows there are would require an additional content property or method to retrieve <code>$("tbody tr").size()</code>. The table is a repeating data structure and it would be nice to treat it as one!</p>
<p>This ought to be possible bearing in mind 3 things:</p>
<ol>
<li>The type of a content property is simply whatever you return from the defining closure, there’s no reason we can’t return a <code>List<BookRow></code>.</li>
<li>There’s nothing special about the expression that constructs the module itself: <code>module BookRow, $("tbody tr", i)</code> is just a call to a method called <code>module</code> passing a <code>Class<? extends Module></code> which is the module type we want and a <code>Navigator</code> pointing to the module’s root element.</li>
<li>The Geb <code>Navigator</code> class returned by the <code>$</code> expression implements <code>Iterable<Navigator></code> and can be treated like a <code>List</code> of all the selected HTML elements.</li>
</ol>
<p>In fact we can get a <code>List<BookRow></code> easily enough if we redefine the <code>bookResults</code> property like this:</p>
<pre><code>static content = {
bookResults {
$("tbody tr").collect {
module BookRow, it
}
}
}
</code></pre>
<p>The key here is that we iterate over the <code>tr</code> elements inside the content definition collecting a new <code>BookRow</code> instance for each one. Now the page object doesn’t require the test to pass in the index of the row it’s interested in. This enables our test to do some much more powerful and interesting things:</p>
<pre><code>expect:
bookResults.size() == 4
bookResults[0].title == "Zero History"
bookResults.title.unique() == ["Zero History", "Spook Country", "Pattern Recognition"]
bookResults.every { it.author == "William Gibson" }
bookResults[2..3].every { it.format == "Paperback" }
bookResults.price.sum() == 34.27
</code></pre>
<p>I’ve tried to show a couple of reasonably simple examples here. Others are easy to imagine; a <code>Map</code> representing the <code>dt</code> and <code>dd</code> elements inside an HTML definition list, a list of modules representing a group of labelled radio buttons or news items with images and links, a tree-like multi-level navigation structure, etc.</p>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com19tag:blogger.com,1999:blog-9390811.post-69860338727307693142010-09-24T13:48:00.001+01:002010-09-27T09:40:23.672+01:00Stubbing access to the g:message tag in unit testsGrails controllers and tag libs can access any tag as though it were a method. The most common use for this is probably accessing i18n messages via the <code><a href="http://grails.org/doc/latest/ref/Tags/message.html">g:message</a></code> tag. However, because tag access is magic wired up by Grails it's not available in unit tests without some effort.<br />
<br />
This is a perennial nuisance. Not exactly difficult to solve and yet something I find myself solving over and over in different tests and different projects.<br />
<br />
I've come up with what I think is a pretty good and re-usable solution. It allows you to specify messages if you want to, or just use the message code if it's not something you care about in a particular test. As an aside, at a unit test level, I think testing that the correct message <em>code</em> is being used is probably the right thing to do; I'd leave testing actual message text to end-to-end tests.<br />
<br />
Here's an example. Imagine we're testing the following controller that displays a simple greeting:<script src="http://gist.github.com/595061.js?file=GreetingController.groovy"></script><noscript><pre>class GreetingController {
def index = {
[message: message(code: "greeting.message", args: [params.name])]
}
}</pre></noscript><br />
<br />
Here's a spec that shows the behaviour both when a message is specified and when it isn't:<script src="http://gist.github.com/595061.js?file=GreetingControllerSpec.groovy"></script><noscript><pre>import grails.plugin.spock.*
import org.springframework.context.*
import org.springframework.context.support.*
import spock.lang.*
class GreetingControllerSpec extends ControllerSpec {
@Shared def messageSource = new StaticMessageSource()
@Shared def pirateEnglish = new Locale("en", "BV")
def setupSpec() {
messageSource.useCodeAsDefaultMessage = true
messageSource.addMessage "greeting.message", pirateEnglish, "Ahoy there {0}!"
}
def setup() {
mockMessageTag(controller, messageSource)
}
@Unroll
def "greeting is rendered by index action"() {
given:
if (name) controller.params.name = name
if (locale) controller.request.addPreferredLocale(locale)
expect:
controller.index() == [message: message]
where:
name | locale | message
null | null | "greeting.message"
"Rob" | null | "greeting.message"
"Rob" | pirateEnglish | "Ahoy there Rob!"
}
// in reality this would be static imported from a helper class
static void mockMessageTag(artefact, MessageSource messageSource) {
artefact.metaClass.message = { attrs ->
messageSource.getMessage(attrs.code, attrs.args as Object[], delegate.request.locale)
}
}
}</pre></noscript><br />
<br />
A few things to note:<ol><li>The stubbed message tag returns the code if there is no message defined</li>
<li>message arguments are ignored unless there is a message defined</li>
</ol><br />
Although in the example I've used <a href="http://spockframework.org/">Spock</a>, this technique would work equally well with <a href="http://grails.org/doc/latest/guide/9.%20Testing.html#9.1%20Unit%20Testing">JUnit tests extending <em>ControllerUnitTestCase</em></a>. It will also work just as well for tag libs tests extending <em>TagLibUnitTestCase</em> or <em>TagLibSpec</em>.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com11tag:blogger.com,1999:blog-9390811.post-30780898694648894732010-08-12T22:46:00.005+01:002010-08-12T23:51:27.623+01:00Auto-generate Spock specs for Grails artifactsWhen creating artifacts such as domain classes, controllers and tag libs Grails generates a <em>JUnit</em> test case. If, like me, you're digging writing specifications with <a href="http://spockframework.org/">Spock</a> you'd probably rather have Grails generate one of those. The last thing I want is to manually transform every generated test case into a specification for every artifact I create.<br />
<br />
It's very simple to create a <em>CreateUnitSpec</em> or <em>CreateIntegrationSpec</em> script with a template specification. Hooking in to the other types of artifact creation turned out to be fiddlier. Each <em>create-*</em> command calls a Closure called <em>createUnitTest</em>. Reassigning that Closure should be the solution. The trick is in figuring out where that can be done.<br />
<br />
Any time one of its <a href="http://gant.codehaus.org/">Gant</a> targets is invoked the Grails build system fires an event. You can respond to those events by declaring a closure called <code>event<target name>Start</code> in <code>scripts/_Events.groovy</code>. The only Gant target directly invoked when an artifact is created is called <em>'default'</em>. It is possible to intercept that although that means the event handler will be invoked any time <strong>any</strong> Gant target called <em>'default'</em> runs. For this purpose that's no problem since we're just overriding a closure in the build binding.<br />
<br />
The other factor is that the superclass for the unit test is specified by the individual <em>create-*</em> scripts (or defaulted to <em>GrailsUnitTestCase</em>). Rather than having to override those scripts as well, I've just mapped the non-standard unit test superclasses to the Spock equivalents.<br />
<br />
Here's the code for your <code>_Events.groovy</code> script:<script src="http://gist.github.com/521675.js?file=_Events.groovy"></script><noscript><pre>eventDefaultStart = {
createUnitTest = { Map args = [:] ->
def superClass
// map unit test superclass to Spock equivalent
switch(args["superClass"]) {
case "ControllerUnitTestCase":
superClass = "ControllerSpec"
break
case "TagLibUnitTestCase":
superClass = "TagLibSpec"
break
default:
superClass = "UnitSpec"
}
createArtifact name: args["name"], suffix: "${args['suffix']}Spec", type: "Spec", path: "test/unit", superClass: superClass
}
}</pre></noscript><br />
The template specification should be placed in <code>src/templates/artifacts/Spec.groovy</code> and is simply:<script src="http://gist.github.com/521675.js?file=Spec.groovy"></script><noscript><pre>@artifact.package@import spock.lang.*
import grails.plugin.spock.*
class @artifact.name@ extends @artifact.superclass@ {
def "feature method"() {
}
}</pre></noscript><br />
It goes without saying that this is a slightly hairy and it would be great if Grails provided a proper hook for overriding the test generation. I can live with some fun-size evil in <em>_Events.groovy</em> for the sake of the convenience of getting template specs for all my artifacts, though.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com8tag:blogger.com,1999:blog-9390811.post-22801605911782011582010-07-10T14:30:00.006+01:002010-07-10T14:41:55.176+01:00Rendering Grails Joda-Time date inputs cross browser with HTML5, jQuery and Modernizr<p>Yesterday I released a new version of the Grails <a href="http://grails.org/plugin/joda-time">Joda-Time plugin</a> that includes support for the various new <a href="http://diveintohtml5.org/forms.html#type-date" title="HTML5 Date pickers">date and time input types</a> in the HTML5 standard. Right now only <a href="http://opera.com" title="Opera web browser">Opera</a> supports these types with proper date-picker type controls, the other browsers just render them as text inputs. However this doesn’t mean you can’t or shouldn’t start using them right away. There’s a very handy JavaScript library called <a href="http://www.modernizr.com/">Modernizr</a> that you can use to detect the features supported by the client’s browser and render alternatives using script. In this post I’m going to walk through how to combine the Joda-Time plugin, Modernizr and the <a href="http://jqueryui.com/demos/datepicker/">jQuery datepicker</a> to render an HTML5 <em>date</em> input field that will bind to a <em>LocalDate</em> property on a domain object.</p><h2 id="install_the_joda_time_plugin">Install the Joda-Time plugin</h2><p>If you don’t currently have version 1.1+ of the Joda-Time plugin installed, run <code>grails install-plugin joda-time</code>.</p><p>Once the plugin is installed you will need to enable HTML5 support so that data binding will use the HTML5 date/time formats. Simply add the following to your <em>Config.groovy</em></p><pre>jodatime.format.html5 = true
</pre><h2 id="create_a_domain_class_with_a_localdate_property">Create a domain class with a LocalDate property</h2><p>For this example I’ll create a simple domain class representing a person:</p><pre>import org.joda.time.*
import org.joda.time.contrib.hibernate.*
class Person {
String name
LocalDate birthdate
static mapping = {
birthdate type: PersistentLocalDate
}
}
</pre><p>If you have default mappings set up (which the Joda-Time plugin will attempt to do for you when it installs) then you can omit the <em>mapping</em> block but I’ve included it for completeness.</p><p>Execute <code>grails generate-all Person</code> to create a controller and scaffolded views for the <em>Person</em> class. Finally change the <em>create.gsp</em> and <em>edit.gsp</em> files to use an HTML5 input instead of the standard Grails date picker tag. Replace the <code><g:datePicker name="birthdate"…</code> with this:</p><pre><joda:dateField name="birthdate" value="${personInstance.birthdate}"/>
</pre><p>In the unlikely event that all your site’s visitors are using Opera then your work is done at this point. However right now anyone using another browser will have to type in the <em>birthdate</em> value in the correct format in order to get the forms to submit properly which isn’t the friendliest user experience.</p><h2 id="install_jquery_and_jquery_ui">Install jQuery and jQuery-UI</h2><p>You can include jQuery and jQuery-UI by simply downloading the JavaScript files into your app, or linking to them on Google. Alternatively you can use the Grails plugins. If you want to go the plugin route this is what you will need to do. First install the plugins:</p><pre>grails install-plugin jquery-ui
</pre><p>The jQuery plugin is installed automatically by the jQuery-UI plugin.</p><p>Then you will need to add the libraries to your SiteMesh template (or you could include it just on the relevant pages, it doesn’t matter). Add the following in the <em>head</em> section:</p><pre><g:javascript library="jquery" plugin="jquery"/>
<jqui:resources components="datepicker" mode="normal" />
</pre><h2 id="install_modernizr">Install Modernizr</h2><p>Download Modernizr and put it in <em>web-app/js/modernizr</em>. You can link to the script direct from there or define a library by adding this to <em>BootStrap.groovy</em>:</p><pre>import org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib
class BootStrap {
def init = { servletContext ->
JavascriptTagLib.LIBRARY_MAPPINGS.modernizr = ["modernizr/modernizr-1.5.min"]
}
</pre><p>Then include Modernizr in your SiteMesh template by adding the following in the <em>head</em> section:</p><pre><g:javascript library="modernizr"/>
</pre><p>To get Modernizr to work its magic you should add a <code>class="no-js"</code> to the <em>html</em> element at the top of your SiteMesh template. Modernizr will replace this when the document loads with a whole bunch of classes that it uses to detect the various features supported by the browser.</p><h2 id="bind_the_jquery_ui_datepicker_to_the_field">Bind the jQuery-UI datepicker to the field</h2><p>The last step is to ensure that any time a user hits the page with a browser that doesn’t support a native widget for the <em>date</em> input type they get a jQuery datepicker instead. To do this create a JavaScript file and link to it from your SiteMesh template or the pages using <em>date</em> inputs. The script simply needs to contain the following code:</p><pre>$(document).ready(function() {
if (!Modernizr.inputtypes.date) {
$("input[type=date]").datepicker({dateFormat: $.datepicker.W3C});
}
});
</pre><p>What this does is create a function that runs on page load that uses Modernizr to determine if the <em>date</em> input type is supported and if not initialises a jQuery-UI datepicker for <em>every</em> <code><input type="date"…</code> found in the page. The <code>dateFormat</code> argument ensures the jQuery widget will update the input with the correct date format when a value is selected.</p><p>It’s that simple. Now the <em>create</em> and <em>edit person</em> pages will use the native <em>date</em> input widget when the visitor’s browser supports one and the jQuery widget when it doesn’t.</p><p>So how does it look? Here's a screenshot of the page in Firefox when a visitor has focused the <em>date</em> input:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpFBFtKhZADjXNike5oNe-Ts2alyj21Y8lPIQoNlI3V2PeZby_BWGIlLgOcVGZI3RScvbe9o2xJZennspcgWTriDb-jsqbzneNLcUV1e25tIluEOYk-8viNUSqAWgrB68nFHKq/s1600/firefox.png" imageanchor="1" style="margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpFBFtKhZADjXNike5oNe-Ts2alyj21Y8lPIQoNlI3V2PeZby_BWGIlLgOcVGZI3RScvbe9o2xJZennspcgWTriDb-jsqbzneNLcUV1e25tIluEOYk-8viNUSqAWgrB68nFHKq/s320/firefox.png" /></a></div><p style="clear: both;">Here's the same thing rendered in Opera using the native datepicker widget (yes, you could be forgiven for thinking the jQuery version is prettier):</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw7fsnTSbvuthnXHpRhDPlqM-nrM32WYgI9kBzbbtCcIeQodtuhieP3D-loUz9cE6euOVi8tRxZf1qjDkNJKhJE258GgPUkDQYcXp-rxq87cHhBTSbQgcHRZ2FGa7yhyphenhyphen938MgH/s1600/opera.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw7fsnTSbvuthnXHpRhDPlqM-nrM32WYgI9kBzbbtCcIeQodtuhieP3D-loUz9cE6euOVi8tRxZf1qjDkNJKhJE258GgPUkDQYcXp-rxq87cHhBTSbQgcHRZ2FGa7yhyphenhyphen938MgH/s320/opera.png" /></a></div><p style="clear: both;">With a little adaptation the same thing can be done for the other input types; <em>month</em>, <em>week</em>, <em>time</em>, <em>datetime</em> and <em>datetime-local</em>. Of those <em>month</em> should work perfectly by adding this to your script:</p><pre>if (!Modernizr.inputtypes.month) {
$("input[type=month]").datepicker({dateFormat: 'yy-mm');
}
</pre><p>Other types would require different widgets to enable users to input the time portion of the value. There are several jQuery based options available. Of course, instead of jQuery you could use <a href="http://developer.yahoo.com/yui/calendar/">YUI</a>, <a href="http://script.aculo.us/">script.aculo.us</a> or any other date/time widgets. I’ve gone with jQuery because I’m familiar with it and the initialisation is beautifully simple even if you’ve got a number of different inputs on a page.</p>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com11tag:blogger.com,1999:blog-9390811.post-15431436966271028232010-06-29T16:27:00.001+01:002010-06-29T17:36:14.395+01:00Acyclic relationship validation in GrailsA common domain class use-case is for a self-referential relationship that must not be circular (a <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">directed acyclic graph</a>). For example, a <em>Person</em> class may have a <em>parent</em> property that is a many-to-one relationship with another <em>Person</em> instance. However a given <em>Person</em> cannot be his own <em>parent</em> or ancestor.<br />
<br />
We're using just such a relationship for trees of pages that inherit certain characteristics from their ancestors. In order to validate that our users aren't setting up circular references I implemented the following constraint:<script src="http://gist.github.com/457351.js?file=AcyclicConstraint.groovy"></script><noscript><pre>import org.codehaus.groovy.grails.validation.AbstractConstraint
import org.springframework.validation.Errors
class AcyclicConstraint extends AbstractConstraint {
static final String DEFAULT_MESSAGE_CODE = "default.acyclic.violation.message"
static final String NAME = "acyclic"
private boolean validateConstraint
protected void processValidate(Object target, Object propertyValue, Errors errors) {
if (validateConstraint && propertyValue) {
if (isCyclic(target, propertyValue)) {
def args = [constraintPropertyName, constraintOwningClass, propertyValue] as Object[]
rejectValue(target, errors, DEFAULT_MESSAGE_CODE, "${NAME}.violation", args)
}
}
}
void setParameter(Object constraintParameter) {
if (!(constraintParameter instanceof Boolean)) {
throw new IllegalArgumentException("Parameter for constraint [$NAME] of property [$constraintPropertyName] of class [$constraintOwningClass] must be a boolean value")
}
validateConstraint = constraintParameter
super.setParameter(constraintParameter)
}
boolean supports(Class type) { true }
String getName() { NAME }
private boolean isCyclic(original, node) {
boolean cyclic = false
while (node != null) {
if (node.id == original.id) {
cyclic = true
break
}
node = node."$propertyName"
}
return cyclic
}
}</pre></noscript>Then I just needed to register my new constraint by adding <code>ConstrainedProperty.registerNewConstraint(AcyclicConstraint.NAME, AcyclicConstraint)</code> to <em>grails-app/conf/spring/resources.groovy</em>. Using the constraint is as simple as this:<pre>class Person {
String name
Person parent
static constraints = {
parent acyclic: true
}
}</pre>The constraint can be mixed with others such as <code>nullable: true</code>. The really nice thing is that the constraint implementation doesn't reference any of my domain classes directly, meaning it can be re-used in any other domain class.<br />
<br />
When you're using similar validation logic in multiple classes defining a constraint like this is a much better option than using a <em>validator</em> closure and like many things in Grails it turns out to be pretty easy to implement.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com80tag:blogger.com,1999:blog-9390811.post-60262246765213616232010-06-24T06:57:00.001+01:002010-06-28T09:08:51.631+01:00Defaulting Joda Time Hibernate Types with GrailsGrails 1.2 added the ability to define default Hibernate mappings that apply to all GORM classes. It turns out this is incredibly useful if you're using Joda-Time types instead of <em>java.util.Date</em> in your domain objects. Previously you had to specify the Hibernate user type for every single field, like this:<pre>import org.joda.time.*
import org.joda.time.contrib.hibernate.*
DateTime dateCreated
DateTime lastUpdated
LocalDate birthday
static mapping = {
dateCreated type: PersistentDateTime
lastUpdated type: PersistentDateTime
birthday type: PersistentLocalDate
}</pre>Now you can just add this to your <em>Config.groovy</em> once and do away with the type mappings in the individual classes:<pre>grails.gorm.default.mapping = {
"user-type" type: PersistentDateTime, class: DateTime
"user-type" type: PersistentLocalDate, class: LocalDate
}</pre><strong>Correction:</strong> I had previously posted that the method call in the default mapping DSL could be anything, but on further investigation it turns out it has to be <em>user-type</em>. Apologies for the error.<br />
<br />
I'll look into the possibility of the Joda-Time plugin doing this itself to make things even easier.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com115tag:blogger.com,1999:blog-9390811.post-42220616299736812712010-06-15T14:18:00.005+01:002010-06-16T09:06:58.260+01:00Export Selenium IDE scripts for GrailsThanks to the <a href="http://adam.goucher.ca/?p=1352">documentation</a> provided on <a href="http://adam.goucher.ca/">Adam Goucher's blog</a> I've created a simple Firefox plugin that extends the <a href="http://seleniumhq.org/projects/ide/">Selenium IDE</a> and adds formatters that allow you to export a script as a <a href="http://robfletcher.github.com/grails-selenium-rc/docs/manual/index.html">Grails Selenium RC</a> test case. You have the option of JUnit 3 (extends <em>GroovyTestCase</em>, uses <em>assertEquals</em>) or JUnit 4 (doesn't extend anything, uses annotations and <em>assertThat</em>) formats.<br />
<br />
I think everything is working. There are some things I'd still like to do:<ul><li>Custom commands are currently exported as commented out which they don't need to be given Grails Selenium RC test cases can call Javascript extension functions directly.</li>
<li>I haven't yet figured out how to output a command such as <pre>selenium.waitForAlertPresent()</pre>rather than <pre>selenium.waitFor {
selenium.isAlertPresent()
}</pre></li>
</ul><br />
The Firefox plugin is available from <a href="http://bit.ly/daOJpD">Selenium HQ</a>. You will need to have Selenium IDE installed for it to work, obviously. Once installed you should find options <ul><li><em>Export Test Case As -> Grails Selenium RC (JUnit 3)</em></li><li><em>Export Test Case As -> Grails Selenium RC (JUnit 4)</em></ul>have been added to Selenium IDE's <em>File</em> menu.<br />
<br />
Whilst I would certainly not leave the exported test case as is it's a quick way to get started. From the exported script you can easily refactor out some page objects or helper methods.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com306tag:blogger.com,1999:blog-9390811.post-88427054239331473032010-05-28T13:27:00.000+01:002010-05-28T13:27:46.264+01:00Grails Spring Events PluginFollowing on from <a href="http://adhockery.blogspot.com/2010/05/asynchronous-application-events-in.html">my last post</a> I've developed a Grails plugin that packages the asynchronous events behaviour up and adds some extra useful functionality.<br />
<br />
In addition to the asynchronous event processing the plugin gives you:<ul><li>A <em>publishEvent</em> method attached to all domain classes, controllers and services.</li>
<li>A Hibernate session bound to the listener thread for the duration of the notification so that listeners can access lazy-loaded properties, etc.</li>
<li>The ability to have a "retry policy" for certain types of failed notifications on individual listeners. This is particularly useful for listeners that do things like invoking external web-services that may be periodically unavailable.</li>
</ul><br />
To install the plugin just use:<pre>grails install-plugin spring-events</pre><br />
The code and some more detailed documentation is on <a href="http://github.com/robfletcher/grails-spring-events">GitHub</a>. I'll be migrating the docs to the plugin's page on grails.org soon.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com9tag:blogger.com,1999:blog-9390811.post-57300544592395905182010-05-03T21:59:00.003+01:002010-05-04T06:56:34.147+01:00Asynchronous application events in GrailsOn the project for my current client we've been using JMS in a rather naïve way for some time now. We've also experienced a certain amount of pain getting JMS and ActiveMQ configured correctly. However, all we're really using JMS for is asynchronous event broadcasting. Essentially we have a handful actions such as flushing hardware caches and notifying external systems that take place when a document changes. We don't want these things blocking the request thread when users save data.<br />
<br />
After wrestling with JMS one too many times we decided to take a look at Spring's event framework instead. It turns out it's extremely easy to use for these kinds of asynchronous notifications in a Grails application.<br />
<br />
Essentially any artefact can publish an event to the Spring application context. A simple publishing service can be implemented like this:<pre>import org.springframework.context.*
class EventService implements ApplicationContextAware {
boolean transactional = false
ApplicationContext applicationContext
void publish(ApplicationEvent event) {
println "Raising event '$event' in thread ${Thread.currentThread().id}"
applicationContext.publishEvent(event)
}
}</pre>So a Grails domain class can then do something like this:<pre>def eventService
void afterInsert() {
eventService.publish(new DocumentEvent(this, "created"))
}
void afterUpdate() {
eventService.publish(new DocumentEvent(this, "updated"))
}
void afterDelete() {
eventService.publish(new DocumentEvent(this, "deleted"))
}</pre>Grails services make ideal <a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/ApplicationListener.html"><em>ApplicationListener</em></a> implementations. As services are singleton Spring beans they are automatically discovered by Spring's event system without any configuration required. For example:<pre>import org.springframework.context.*
class EventLoggingService implements ApplicationListener<DocumentEvent> {
boolean transactional = false
void onApplicationEvent(DocumentEvent event) {
println "Recieved event '$event' in thread ${Thread.currentThread().id}"
}
}</pre>Of course, multiple listeners can respond to the same events.<br />
<br />
If you run the code you will notice that by default Spring's event system processes events synchronously. The <em>EventService</em> and <em>ApplicationListener</em> will print out the same Thread <em>id</em>. This is not ideal if any of the listener implementations might take any time. Luckily it's easy to override the <a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/event/ApplicationEventMulticaster.html"><em>ApplicationEventMulticaster</em></a> bean in <code>resources.groovy</code> so that it uses a thread pool:<pre>import java.util.concurrent.*
import org.springframework.context.event.*
beans = {
applicationEventMulticaster(SimpleApplicationEventMulticaster) {
taskExecutor = Executors.newCachedThreadPool()
}
}</pre>Running the code again will show the event being published in one thread and consumed in another. If you have multiple listeners each one will be executed in its own thread.<br />
<br />
Oddly, I would have thought it was possible to override the <em>taskExecutor</em> property of the default <em>ApplicationEventMulticaster</em> in <code>Config.groovy</code> using Grails' <a href="http://grails.org/doc/latest/guide/14.%20Grails%20and%20Spring.html#14.6%20Property%20Override%20Configuration" title="Property Override Configuration in the Grails User Guide">property override configuration</a>, but I found the following didn't work:<pre>beans {
applicationEventMulticaster {
taskExecutor = Executors.newCachedThreadPool()
}
}</pre>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com22tag:blogger.com,1999:blog-9390811.post-20564049875597426662010-05-03T07:59:00.002+01:002010-05-03T08:23:07.236+01:00Selenium RC plugin v1.0The Selenium RC plugin for Grails has hit version 1.0 with: <ul><li>Firefox 3.6 support</li><li>grabbing of screenshots on test failures</li><li>the ability to call JavaScript user extensions on the <em>selenium</em> object as though they were regular Groovy methods</li></ul>among other features. Check out the documentation at <a href="http://robfletcher.github.com/grails-selenium-rc">http://robfletcher.github.com/grails-selenium-rc</a> and install with <code>grails install-plugin selenium-rc</code>.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com85tag:blogger.com,1999:blog-9390811.post-46197134616773992382010-05-03T06:35:00.001+01:002010-05-03T06:38:31.803+01:00Building your app on Hudson with Multiple Grails versionsFor my Grails plugins I generally write a test project (or more than one). I thought it would be useful to be able to run these against multiple versions of Grails on my build server so I can spot any incompatibilities with the versions the plugin is supposed to support.<br />
<br />
Using <a href="http://hudson-ci.org/">Hudson</a> this turned out to be pretty straightforward.<br />
<br />
You will need all the Grails versions you want to test against installed on your Hudson box. I put them in <code>/opt</code> so replace that with wherever you have them in the steps below. Also, if you want the builds to run in parallel and will be running any functional tests you'll need the <a href="http://wiki.hudson-ci.org/display/HUDSON/Port+Allocator+Plugin">Hudson Port Allocator plugin</a>.<br />
<br />
<ul><li>Start by creating a new job in Hudson and choosing <em>"Build multi-configuration project"</em>.</li>
<li>The configuration dialog has an extra section <em>"Configuration Matrix"</em> where you can set up the different config combinations that will run. We're just interested in varying the Grails version so check the <em>"Axes"</em> and create a new axis named <em>"GRAILS_VERSION"</em> with the different versions you want in the <em>"values"</em> box, e.g. "<code>1.2.0 1.2.1 1.2.2 1.3.0.RC2</code>"</li>
<li>Set up your source code repository and build triggers as you would for any other project.</li>
<li>If you want to run the builds in parallel and are running any functional tests you will need to make sure that Grails starts up on a unique port. In the <em>"Build environment"</em> section add a new <em>"Plain TCP port"</em> named <em>"GRAILS_PORT"</em>. If you're running anything else that needs a port such as a Selenium server you'll need one for that as well.</li>
<li>Add an <em>"Execute shell"</em> build step. Unfortunately the Hudson Grails plugin does not allow you to use a variable to specify the Grails version so you'll have to go old-school:<br />
<pre>export GRAILS_HOME=/opt/grails-$GRAILS_VERSION
export PATH=$GRAILS_HOME/bin:$PATH
# assign Grails a unique port (you can skip this if you're only running unit/integration tests)
export JAVA_OPTS="$JAVA_OPTS -Dserver.port=$GRAILS_PORT"
grails clean
grails upgrade --non-interactive
grails test-app --non-interactive</pre></li>
<li>Check <em>"Publish JUnit test result report"</em> in the <em>"Post-build Actions"</em> section and specify <code>target/test-reports/*.xml</code> as the <em>"Test report XMLs"</em></li>
</ul><br />
When you run the Hudson job you should see it kick off one sub-job for each Grails version. Each will check out the project, upgrade it to the relevant Grails version and run the tests.<br />
<br />
I have my plugin test projects triggered by the plugin build and have them grab the plugin zip itself from the archived artefacts in the plugin's Hudson job. So I've added this before the <code>grails test-app</code> step:<pre>grails install-plugin http://my.hudson.server/hudson/job/my-plugin/lastSuccessfulBuild/artifact/my-plugin-1.0.zip --non-interactive
</pre>There's a <a href="http://jira.codehaus.org/browse/GRAILS-6223">bug</a> in Grails 1.3.0.RC2 that means you will need to split this into a <code>wget</code> followed by installing the zip from a file path rather than a URL. This is fixed in trunk so won't be a problem in Grails 1.3 final.<br />
<br />
If you're using SVN I think you may need to revert any changes the <code>grails upgrade</code> has made to <code>application.properties</code>, etc. otherwise you'll get merge conflicts on the next run. This does not seem to be a problem with Git.Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com5tag:blogger.com,1999:blog-9390811.post-49607195094173366132010-04-21T14:26:00.002+01:002010-04-21T14:27:51.881+01:00A Grails JUnit 4 test template<p>Grails 1.3 upgrades the bundles JUnit to the newer JUnit 4 API. However, the test template used to generate classes by the Grails <em>create-*</em> scripts is still very JUnit 3-ish. Here's a replacement that will generate a skeleton test using JUnit 4 conventions:<p><script src="http://gist.github.com/373794.js?file=Tests.groovy"></script><noscript><pre>@artifact.package@import grails.test.*
import org.junit.*
import static org.junit.Assert.*
import static org.hamcrest.CoreMatchers.*
import static org.junit.matchers.JUnitMatchers.*
class @artifact.name@ {
@Before void setUp() {
}
@After void tearDown() {
}
@Test void something() {
}
}</pre></noscript><p>To use this just run <code>grails install-templates</code> then copy the contents over the file <em>src/templates/artifacts/Tests.groovy</em>. You can delete anything else in the <em>src/templates</em> directory that you don't need. Then every time you use a Grails command such as <code>grails create-service foo</code> the generated test will use the JUnit 4 template.</p>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com3tag:blogger.com,1999:blog-9390811.post-67693737303041336842010-03-17T06:53:00.003+00:002010-03-17T06:58:24.554+00:00Customising collection binding in GrailsFollowing up on my earlier post about <a href="http://adhockery.blogspot.com/2010/02/using-custom-data-binder-with-grails.html">using custom <tt>PropertyEditor</tt> implementations to bind association properties</a> I started looking into the options for custom binding one-to-many associations.<br />
<br />
For example, tags, as seen on many sites (including Blogger) would typically be modelled as a <tt>Set</tt> of either <tt>String</tt> or some kind of <em>Tag</em> domain object. With <em>tag</em> functionality we really don't want to be selecting tags using a multi-select combo box. It would be ridiculously huge and hard to find anything in it. An auto-completer that recognises commas as delimiters would be the way to go. Script.aculo.us has an <a href="http://wiki.github.com/madrobby/scriptaculous/ajax-autocompleter">AJAX Autocompleter</a> that can handle this kind of tokenised input. Similarly, the Grails RichUI plugin offers an <a href="http://grails.org/plugin/richui#AutoComplete">autocomplete tag</a> that uses a Yahoo! UI component. There are comparable controls available if you're using jQuery or some other Javascript library. What you will end up with is the browser submitting a single parameter containing a comma-separated String of tag names. The trick is to turn that into a collection of <tt>String</tt> or <tt>Tag</tt> domain instances.<br />
<br />
For the former case binding is pretty easy. All you need is a property editor that converts a comma-separated String into a <tt>Set</tt> of <tt>String</tt> and <em>vice-versa</em>:<script src="http://gist.github.com/334988.js"></script><noscript><pre>class TagListEditor extends PropertyEditorSupport {
void setAsText(String text) {
value = text.split(/,\s*/) as Set
}
String getAsText() {
value?.join(", ")
}
}</pre></noscript><br />
Then just register the editor in your <tt>PropertyEditorRegistrar</tt> implementation:<pre>registry.registerCustomEditor List, "tags", new TagListEditor()</pre><br />
If you've gone the latter route and used a domain object to represent a <em>tag</em> things have been trickier. Grails didn't allow you to register custom property editors against one-to-many association properties as it considered it knew how to handle such binding.<br />
<br />
I raised and fixed a <a href="http://jira.codehaus.org/browse/GRAILS-5985">Grails issue</a> to allow for registering custom editors on one-to-many properties so from 1.2.2 and 1.3-M2 you will be able to use a property editor something like this:<script src="http://gist.github.com/334989.js"></script><noscript><pre>class TagListEditor extends PropertyEditorSupport {
void setAsText(String text) {
value = text.split(/,\s*/).collect {
Tag.findByName(it) ?: new Tag(name: it)
} as Set
}
String getAsText() {
value?.name?.join(", ")
}
}</pre></noscript>Robhttp://www.blogger.com/profile/01855523354151116481noreply@blogger.com3