DevJam Presentation on Groovy/Grails

January 10, 2009 – 8:54 am

This past week I presented on Groovy/Grails to a group of developers here in Minneapolis. Afterwards we had a panel discussion (fishbowl style) and dove into a wide array of topics ranging from dynamic vs. static typed languages, when to consider using Groovy/Grails and when NOT to. It was a great discussion and it was fun to hear so many different perspectives.

I’ve posted a few links for those interested in in learning more and the slides can be seen on SlideShare: Groovy Grails DevJam Jam Session

Vote for better Cobertura support in Groovy

December 16, 2008 – 6:04 am

Luke Daley pointed out that there’s an open issue on the Groovy task list that would help with better Cobertura support for Groovy:

http://jira.codehaus.org/browse/GROOVY-3118

Cobertura support is already pretty good, but there are some cases where coverage doesn’t quite show up at 100% when it should.

Go set up a profile, login, and vote!

Overhead of setUp and tearDown in unit tests

December 3, 2008 – 9:39 pm

I was watching the output of my Grails unit tests and noticed that tests using the mockDomain feature of the new Testing Plugin seemed to run just slightly slower than straight up unit tests.  This makes sense, as these tests are doing some meta programming magic to add mock dynamic methods and also remove them after each test run – and that takes a little extra time. But time is the enemy of testing, and I want my tests to run as fast as possible. That way I’m not discouraged from writing them or running them on a consistent basis.

So I’ve started writing tests a little differently and have been trying to reduce the number of times setUp() and tearDown() are called within a test class.  This is probably a good practice, regardless of the unit testing mechanism you’re using. Here’s an example – I used to have really verbose test methods, like this:

testFirstNameBlankConstraint(){...}
testFirstNameNullableConstraint(){...}
testFirstNameMaxSizeConstraint(){...}
testFirstNameValid(){...}

I like this pattern because each test method tested one thing – so if the test method failed, it was pretty obvious what went wrong.

However, setUp and tearDown methods were being called for each of these test methods which added some extra time to run the test suite. In a relatively small project, the time is so negligible it doesn’t matter. But on a large project with thousands of tests, it can be a noticeable difference.

Now when I’m writing my tests, I set ‘em up more like this:

testFirstNameConstraint() {
    // some test code
    assertEquals ("blank constraint", ..., ...)
 
    // some test code
    assertEquals ("null constraint", ..., ...)
 
    // some test code
    assertEquals ("max size constraint", ..., ...)
 
    // some test code
    assertEquals ("valid", ..., ...)
}

In this example, the same testing is occurring, but I have only one test method instead of four (three less calls to setUp and tearDown). By passing a message as the first parameter to the assertions, I can still quickly determine which assertion failed, and my test suite runs more quickly.

Controller.$_closure1 – what? Oh, you mean .index()!

November 20, 2008 – 10:19 pm

So it’s been bugging me for a while that the action names within a controller always showed up like this on my code coverage reports:

Well, no longer! Version 0.9 of the Grails Code Coverage plugin now does some post processing on the Cobertura reports that replace the Controller.$_closure1 ugliness with the matching action name:

It’s not the most efficient post processing in the world – I’m basically iterating through all the controller actions and then replacing all occurrences of those class names with the action names in the report HTML files. If you find the post processing to be too annoying, you can turn it off by passing the “-nopost” argument to the command, like this:

grails test-app-cobertura -nopost

Thanks to Burt Beckwith and others on the grails mailing list for proposing options on how to line up the closure class names with the variable names to which they are assigned in the controller.

It only works for the HTML reports right now…I’ll work on adding it to the XML version of the reports next.

To install the plugin, type the following command:

grails install-plugin code-coverage

Added generate-unit-test-case script to Test Template plugin

November 16, 2008 – 7:46 pm

As pointed out in the docs for the Grails Testing Plugin, constraints often contain a lot of logic for your application and are rarely tested. To help out with that, the Test Template plugin now provides a script that will create a stub of a unit test for you for a given domain class.
For example, say you had the following domain class:

class Book {
	String title
	String subTitle
	Date publishedDate
	static constraints = {
		title(nullable:false, blank:false, size:1..100)
		publishedDate(nullable:true)
	}	
}

With the plugin installed, type “grails generate-domain-unit-test Book”

The plugin will generate and stub out a unit test for you in test/unit/BookUnitTests.groovy. It’s not completely magic – you still need to do some work now:

  • in the setup method, fill in all the properties that would make your domain class validate
  • in each test method, write test code that will test your constraints. The plugin provides comments indicating which constraints are applied to a given property, you just need to write the test code.

Here’s what a stubbed unit test looks like out of the box:

import grails.test.GrailsUnitTestCase
class BookUnitTests extends GrailsUnitTestCase {
    Book book 
    void setUp() {
        super.setUp()
        // in testing-plugin 0.4 you can just do "mockForConstraintsTests(Book)" instead of these two lines
        registerMetaClass(Book) 
        grails.test.MockUtils.prepareForConstraintsTests(Book)
	// TODO - fill out this book instance so it validates
	book = new Book()
        assertTrue "setup method: book should validate", 
			book.validate()
        }
	void testTitleConstriants() {		 
		//test org.codehaus.groovy.grails.validation.NullableConstraint@de1237[false]  
		//test org.codehaus.groovy.grails.validation.BlankConstraint@7bc5fd[false]  
		//test org.codehaus.groovy.grails.validation.SizeConstraint@36f09[1..100] 
	}	
	void testPublishedDateConstriants() {		
		//test org.codehaus.groovy.grails.validation.NullableConstraint@6ec9d4[true] 
	}	
	void testSubTitleConstriants() {		
		//test org.codehaus.groovy.grails.validation.NullableConstraint@849937[false] 
	}	
}

This is helpful in reminding you what you actually need to test – for example, did you remember that by not defining a constraint for the ’subTitle’ property, grails makes it a non-nullable field?

By the way, the script also works with the uber generate feature of Grails 1.0.4 – so if you have lots of domain classes and want to generate unit tests for all of them in one fell swoop, you can type:

grails generate-domain-unit-test "*"

and it will stub out unit tests for all your domain classes.

I’m thinking future versions of the plugin could go even further by offering:

  • A ‘verbose’ template that would create multiple test methods for each possible test scenario for a given constraint, for instance a ’size:5..100′ constraint could generate test methods for:
    • a string with a size of 4 (e.g. less than the minimum)
    • a string with a size of 101 (e.g. more than the maximum)
    • a string with a size of 50 (e.g. within the bounds of the constraint)
  • Actually write the test code. Not sure if I’m totally warmed up to this idea yet, but it may be worth looking into. Contributions welcome, of course :)

Give it a shot. You can install the plugin by running the following commands:

grails install-plugin testing
grails install-plugin test-template