Music, software, life… and stuff.
[ Twitter ] [ GitHub ] [ Linked In ]
Spock has an interesting new feature coming in 0.5 (but its available now in recent builds of 0.5-SNAPSHOT) integrating the Hamcrest matching library, which is an API for testing that something meets certain criteria. It’s always been possible to use Hamcrest with Spock but there is now a more convenient syntax. The expressiveness of Groovy generally makes Hamcrest not quite as generally useful as it would be when testing with plain Java, but it can still make your tests more concise and expressive when you have complex matching to do.
A classic example is for matching a value against another value within a certain error margin. Hamcrest comes with the closeTo matcher for this. This is how you might use it in a JUnit test…
import static org.hamcrest.Matchers.closeTo
import static org.hamcrest.MatcherAssert.assertThat
class HamcrestTests extends GroovyTestCase {
def testIt() {
assertThat(1.9d, closeTo(2, 0.5))
}
}
This test will pass because the actual value 1.9d (the d tells groovy it’s a Double and not a BigDecimal) is within ± 0.5 of 2. The closeTo method is what’s known as a matcher factory (i.e. it returns an instance of org.hamcrest.Matcher)
Using Spock’s new convenient matcher syntax, we write the above as…
import spock.lang.Specification
import static org.hamcrest.Matchers.closeTo
class HamcrestSpec extends Specification {
void "test closeTo"() {
expect:
1.9d closeTo(2, 0.5)
}
}
Nice and concise isn’t it. The syntax is essentially…
«value» «org.hamcrest.Matcher»
There is also another variant…
import spock.lang.Specification
import static spock.util.matcher.MatcherSupport.that
import static org.hamcrest.Matchers.closeTo
class HamcrestSpec extends Specification {
void "test closeTo"() {
expect:
that 1.9d, closeTo(2, 0.5)
}
}
This syntax has the advantage that it can be combined with the assert keyword so can be used outside of the then/expect blocks (which the shorthand version can’t).
import spock.lang.Specification
import static spock.util.matcher.MatcherSupport.that
import static org.hamcrest.Matchers.closeTo
class HamcrestSpec extends Specification {
void "test closeTo"() {
setup:
assert that(1.9d, closeTo(2, 0.5))
}
}
As previously mentioned, a lot of the stock matchers that come with Hamcrest are not as useful in Groovy as they are in Java due to Groovy’s many convenience methods and expressive syntax. However, you can easily write your own Hamcrest matchers that are particular to your problem domain to make your tests more concise and maintainable.
Let’s use the example of a Grails application that lets user’s read books online. There is a very simple security model; users and books both belong to groupings and a user must belong to at least one grouping that a book belows to to be allowed to read it. Here is what our domain looks like…
class Book {
String name
static hasMany = [groupings: Grouping]
static belongsTo = Grouping
}
class User {
String name
static hasMany = [groupings: Grouping]
static belongsTo = Grouping
}
class Grouping {
String name
static hasMany = [books: Book, users: User]
}
We could write a custom matcher that checks if a given user can read a given book…
import spock.lang.*
import grails.plugin.spock.*
import org.hamcrest.BaseMatcher
import org.hamcrest.Description
import static org.hamcrest.Matchers.not
class ReadabilitySpec extends IntegrationSpec {
def "test readability"() {
when:
def user = new User(name: "u1").save()
def book1 = new Book(name: "b1").save()
def book2 = new Book(name: "b1").save()
def grouping1 = new Grouping(name: "g1")
grouping1.addToUsers(user)
grouping1.addToBooks(book1)
grouping1.save()
def grouping2 = new Grouping(name: "g2")
grouping2.addToBooks(book2)
grouping2.save()
then:
user canRead(book1)
user not(canRead(book2))
}
def canRead(book) {
[
matches: { user -> user.groupings.any { it in book.groupings } },
describeTo: { Description description -> description.appendText("user in one of groupings ${book.groupings*.name}") }
] as BaseMatcher
}
}
Here we have implemented the canRead matcher factory as an instance method on our spec class. We are also using Groovy’s ability to convert maps into objects that either extend a given class or implement an interface. Here we create a map with the methods that we need to override from the org.hamcrest.BaseMatcher class then use as BaseMatcher to have Groovy create a dynamic subclass for us at runtime (note that this has nothing to do with Spock’s matching support, I am just using it here for conciseness).
We could factor out our custom matcher into a real class and perhaps move the factory method to a separate class as a static method, making it reusable across our project. You could quite easily build up a library of convenient matchers that express your problem domain.
Spock’s new Hamcrest support is yet another great feature that makes your testing easier and more concise. It’s another great tool to have in your bag of tricks when writing tests. For more info and examples, you can check out the test case in the Spock project that exercises this stuff.
Posted: Oct 10th, 2010 @ 4:24 pm
Tags: #software #grails #spock
The “Property Override Configuration” feature is an extremely useful technique for Grails applications. It allows you to specify the values for bean properties in your application configuration, which can be done externally and/or in an environment sensitive manner.
For example, we could easily control the number of simultaneous connections a particular service is allowed to make to a particular thing.
Here is our fictitious service…
class ThingService {
def maxConnections
}
In our Config.groovy we might have…
beans {
thingService {
maxConnections = 10
}
}
environments {
test {
beans {
thingService {
// only use 1 connection when testing
maxConnections = 1
}
}
}
production {
// Load extra config from external location in production
grails.config.locations = ["classpath:thing-config.groovy"]
}
}
On the production classpath we might have a file called “thing-config.groovy” that has…
beans.thingService.maxConnections = 100
So we no have a default value of 10 for our maxConnections property, but overridden in test with a value of 1 and overridden in production with a value of 100. We can also change this value without a recompile in production (though you will need a restart).
That’s all well and good and pretty handy, but you can take it slightly further once you realise how this feature works.
Property Override Configuration works at the bean definition level in Spring. This means that the value you specify is not directly assigned to the corresponding property on the bean in question, but rather is added to the bean definition before Spring goes to work creating your beans (which is effectively the same as changing the original bean definition). This means that you can take advantage of Spring’s rich type conversion features to do some rather cool things.
For example, we can make dealing with the filesystem easier by combining Spring’s resource support with the Property Override Configuration mechanism. Let’s assume we have a service that wants to read a text file that is on the classpath.
Here is our service…
class TextFileReadingService {
File textFile
}
To populate that property you could either write the code yourself to create the instance, define a bean named textFile in resources.groovy and let autowiring set things up, or use Property Override Configuration. If we want to use Property Override Configuration, you might first try…
beans {
textFileReadingService {
textFile = new File(this.class.classLoader.getResource("theTextFile.txt").toURI())
}
}
While that will work, there is an easier way…
beans {
textFileReadingService {
textFile = "classpath:theTextFile.txt"
}
}
This works because Spring implicitly converts the String value we have given to a File object for us, and in doing this treats values with certain prefixes specially. This is part of Spring’s resource abstractions. Another useful prefix is “context:”, which resolves a file path relative to the root of the web app…
beans {
textFileReadingService {
textFile = "context:js/jquery.js"
}
}
Note that Property Override Configuration is particularly useful when working with beans that we don’t define ourselves, such as services, taglibs, controllers etc. If we were defining our own beans and did not need environment sensitivity or externalisation of the value, we could use the same type conversion facilities when definining our beans directly.
If we had a class in src/groovy that looked like…
class TextFileReader {
File textFile
}
We could create a Spring bean for it like so in resources.groovy…
beans = {
textFileReader(TextFileReader) {
textFile = "context:js/jquery.js"
}
}
The point of this example being to illustrate that type conversion is not unique to Property Override Configuration.
Property Override Configuration is a surprisingly useful feature that is generally under publicised. It’s worth adding to your arsenal of techniques, especially combined with the type conversion that Spring offers.
Posted: Oct 6th, 2010 @ 3:41 pm
This will be a discussion of a handy pattern to use to make page identification simple and easy when working with Geb and Grails.
Geb supports (and encourages) using the Page Object Pattern. An aspect of this is having someway of being able to verify that the page object actually does represent the page that the browser is at. Consider filling out a form. When you submit the form you might expect to go to a confirmation page, but because of a validation error you get returned to the form page. In your test code after submitting the form you go on testing for things on the page and the results can be confusing. The best thing to do before testing parts of the page is to test that the page is indeed what you expect it to be. There are other reasons for page identification, but this is the main one.
Geb implements page identification through it’s “at checking”. In short, pages declare an “at” closure that contains some checks of the page structure, and returns true if the actual browser page is what the page object represents.
import geb.*
class ManualPage extends Page {
static at = { $("h1", text: contains("Manual")) }
}
This “at check” is used implicitly when using the browser at(«PageClass») method…
Browser.driver {
to ManualPage
assert at(ManualPage)
}
The at(«PageClass») method does two things:
trueThe use of a Class with the at() method may seem strange. After using Geb for a short amount of time the reasons do become clear. Primarily, your test code is likely to not to declare page changes (such as when content declares a to property). This means that asserting the type of the current page object becomes important.
Writing a good at checker can be hard at times. You want to test enough so that you are sure the page is a match, yet you don’t want to test too much to make your checks fragile.
Fortunately, Grails’ controller/action convention makes identifying pages cost free and definitive (for almost all cases). The trick lies in the controllerName and actionName variables being available in each action’s view implicitly. This allows you to make your Grails GSP templates look something like this…
<html>
<head>
<meta name="pageId" content="${controllerName}.${actionName}" />
…
</head>
<body>
…
</body>
</html>
Every view generated from a controller action in your application now has a unique identifier embedded into the page in an unobtrusive manner.
Geb goes out of it’s way to support using inheritance with page objects. This means that you can define an at checker in a common base class that reads our meta pageId property and have that used for each subclass.
import geb.*
abstract class GrailsPage extends Page {
// To be overridden by subclasses
static controller = null
static action = null
static at = {
// delegate here is the original page _instance_ (i.e. the subclass)
def expectedPageControllerName = delegate.class.controller
if (expectedPageControllerName == null) {
throw new IllegalStateException("${delegate.class} forgot to declare which controller it belongs to")
}
def expectedPageActionName = delegate.class.action
if (expectedPageActionName == null) {
throw new IllegalStateException("${delegate.class} forgot to declare which action it is")
}
def actualPageControllerName = controllerName
def actualPageActionName = actionName
assert actualPageControllerName == expectedPageControllerName
assert actualPageActionName == expectedPageActionName
true // at checkers must return true
}
static content = {
pageId { $("meta", name: "pageId").@content }
controllerName { pageId.split('\\.')[0] }
actionName { pageId.split('\\.')[1] }
}
}
Here we do three things:
static ‘controller’ and ‘action’ properties that subclasses will populate (more on this later)controllerName and actionName bits of content on the page are (consult the Book Of Geb for more on this content DSL)We now have a rock solid page identification mechanism that from here on in in the development and testing of our application costs us almost nothing. The only thing you need to do when writing new page objects is set the controller and action static properties…
class ViewCartPage extends GrailsPage {
static controller = "cart"
static action = "view"
}
Or in the case where all your actions for a particular controller share content, you may want to have an abstract base class for all actions of that controller…
abstract class CartPage extends GrailsPage {
static controller = "cart"
}
class ViewCartPage extends CartPage {
static action = "view"
}
This is made possible by Geb supporting inheritance of content definitions (content definitions are merged) and Groovy supporting a dynamic resolution of static methods and properties.
Given the above classes, the following works…
assert ViewCartPage.controller == "cart"
However, if we were calling this from Java, it would not work. In Java, static methods/properties are never inherited like they are for all intents and purposes in Groovy. This means that when requesting a page class’s “at checker” it will search the inheritance hierarchy for one (e.g. assert ViewCartPage.at == GrailsPage.at). This also means that at any point in the inheritance hierarchy you can override any static method/property defined in a super class (but it only works if calling from Groovy).
We discussed a useful pattern for page identification (“at checking” in Geb parlance) with Geb and Grails. I have used this pattern in anger and have found it to be very useful. Give it a try.
Posted: Aug 26th, 2010 @ 7:22 pm
The following is a proposal for, and a request for comment on, the idea of a semi-structured combination of social and technological systems and norms to initiate, develop and maintain Grails plugins.
Typically, a plugin is born through inspiration or necessity. It’s not uncommon that the original author at some point stops maintaining or developing a frequently-used or promising plugin. There are many reasons for this and they are in no way unique to the Grails ecosystem. People contribute and move on as is their want and well intentioned developers can quickly lose interest in developing a plugin due to roadblocks and lack of knowledge, experience and feedback.As a Software Developer using Grails professionally, the availability of a high quality plugin makes a significant product difference; and conversely an unsuccessful attempt to use a plugin due to bugs or lack of documentation costs real time. Often when finding an issue and fixing it, getting that fix back into the community takes considerable effort in coordinating with the plugin developer/maintainer who may or may not be around.
As a plugin developer, during busy times it can be hard to keep up with bug reports, feature requests and Grails upgrades. It’s also concerning that knowledge and understanding of the plugins I have authored rest largely with myself, creating a single point of failure. It would be much better if there were other people who could (and did) maintain and improve things in my (or any other author’s) absence.
To remedy this situation, I propose that a self-organised, distributed, democratic, collective be formed… to foster, develop and maintain Grails plugins. I am calling this idea the “Grails Plugin Collective” for the time being.
The social structure is what would be the most interesting and, ultimately, enabling. It would allow members to work across plugins, scratching their own itches, and getting those fixes/features into release with minimal effort without risking quality. It would also enable steering and guiding the direction of plugins while allowing members to freely propose ideas and alternatives. Due to Grails’ “convention over configuration” nature, this becomes critically important. Hopefully, the collective wisdom of a group of individuals results in a highly consistent, conventional approach to how plugins work.
I propose that the collective should be an entity outside of VMWare. This does not exclude VMWare employees from participating in the collective by any means, or from having some kind of special role. It purely means that the entity is not bound to VMWare in any way other than through the licensing arrangement of any software owned by VMWare.
I also propose that if a plugin certification scheme is ever established, it be done completely separately to the collective. I imagine that many of the collectivised plugins would aim for certification if at all possible, but in this respect they would be no different to other community plugins.
The collective should aim to operate with the least amount of bureaucracy and procedure that is required. The core idea is that as a democratic structure, all proposals are put to a vote. Members will have a relatively short time frame (proposed: 48 hours) to vote. A certain proportion of the votes cast must be affirmative for the proposal to succeed. It’s likely that there would also be some sort of veto mechanism for things that are extremely time critical.
I image the following kinds of things would be voted on:
Being that what is being proposed is a self-organising, democratic social structure, I am hesitant to be to prescriptive about how such a thing might work in terms of my vision. I am interested in getting other people’s ideas.
An initial membership also needs to be put together. This will be somewhat of a challenge for a democratic outfit. To get the ball rolling, I suggest that the VMWare Grails team propose an initial membership of roughly 10 people (likely including themselves). From there, the collective can self organise and induct new members over time.
So what are your thoughts? Is such an initiative worthwhile? Could it work? Could it succeed in raising and maintaining the quality of selected Grails plugins? Are there other such initiatives that we could learn from? What kind of social practices could be put in place to support rapid development while maintaining consistency and quality?
Feel free to leave your opinion either here or on the grails-user mailing list.
Posted: Jun 7th, 2010 @ 9:29 pm
I haven’t seen many cases of people putting the Grails’ artefact API to use in their application. It’s likely that most Grails’ users aren’t aware that it exists, which in many ways is a good thing… it is after all an implementation concern.
You can however put it to work in your own application.
Perhaps it’s best to discuss what an artefact is in Grails first. An example of an artefact is a service class. Think of what happens when your grails application starts; it finds all the service classes, creates an instance of each (typically) and autowires the dependencies. Grails defines a class whose instances represent a single service class and an associated handler. This is what I am collectively calling the Artefact API.
The biggest reason these days is by far the hot reloading support. That is, if you change an artefact class while the application is running, Grails (with some help from you) will reload the class and you get the changes without a restart. Of course, we are all familiar with this.
There is a more subtle benefit though. You may have some kind of prominent & pervasive concept in your application (like a service is a concept). You might find that creating an artefact for this concept can make your life easier.
Consider some kind of eStore, with a wide range of products. Our products have simple persistence requirements but can have wildly varying behaviours in the system, which are likely to get more complex over time. I try to avoid extensive subclassing of domain objects when the classes primarily vary in behaviour and not data. So we need to find another way to implement the varying behaviour.
ProductHandlerEach product is going to provide a handler (terrible name I know) that is responsible for the majority of the product’s behaviour. Here is our product domain class…
class Product {
String name
// don't want to try and persist the handler
static transients = ['handler']
ProductHandler getHandler() {
// somehow get the handler for this product
}
}
And we have a ProductHandler interface for good measure…
interface ProductHandler {
void setProduct(Product)
boolean isCanBeSold()
}}
One kind of traditional approach would be to have each product persist a key that refers to a particular product handler, and to have each product handler class register itself with some kind of registry.
class Product {
String name
String handlerKey
def productHandlerService // autowired
// don't want to try and persist the handler
static transients = ['handler']
protected handler
ProductHandler getHandler() {
if (!handler) {
handler = productHandlerService[this]
}
handler
}
}
// Our registry
import grails.spring.BeanBuilder
class ProductHandlerService {
def grailsApplication // autowired
static private registry = [:].asSynchronized()
static register(String key, Class handlerClass) {
registry[key] = handlerClass // should check that handlerClass implements ProductHandler
}
protected createBeanBuilder() {
new BeanBuilder(grailsApplication.mainContext, grailsApplication.classLoader)
}
protected instantiateHandler(handlerClass, Product product) {
createBeanBuilder().with {
beans {
handler(handlerClass, product: product) {
// autowire the handler so it can use services etc.
it.autowire = true
}
}
createApplicationContext().getBean('handler')
}
}
def getAt(Product product) {
def handlerClass = registry[product.handlerKey] // assume there is always a handler
instantiateHandler(handlerClass, product)
}
}
// Example Handler (in src/groovy dir)
class OnlyOnTuesdayProductHandler implements ProductHandler {
static {
ProductHandlerService.register('onlyOnTuesday', OnlyOnTuesdayProductHandler)
}
Product product
boolean isCanBeSold() {
new GregorianCalendar().get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY
}
}
This will get the job done (albeit in a cumbersome way), but it suffers from ProductHandler implementations not being hot-reloadable.
ProductHandler artefactWe can make things a bit easier and support hot reloading by creating an artefact for product handlers.
To do this we need a plugin…
class ProductHandlerGrailsPlugin {
def version = "0.1"
def grailsVersion = "1.2.* > *"
// register the artefact handler
def artefacts = [ProductHandlerArtefactHandler]
// watch for any changes in these directories
def watchedResources = [
"file:./grails-app/productHandlers/**/*ProductHandler.groovy",
"file:../../plugins/*/productHandlers/**/*ProductHandler.groovy"
]
// Grails calls this when one of the files matching 'watchedResources' changes.
// We have to actually swap in the new class when the source changes
// There isn't anything special here, it's just boilerplate.
def onChange = { event ->
if (application.isArtefactOfType(ProductHandlerArtefactHandler.TYPE, event.source)) {
def oldClass = application.getProductHandlerClass(event.source.name)
application.addArtefact(ProductHandlerArtefactHandler.TYPE, event.source)
// Reload subclasses
application.productHandlerClasses.each {
if (it.clazz != event.source && oldClass.clazz.isAssignableFrom(it.clazz)) {
def newClass = application.classLoader.reloadClass(it.clazz.name)
application.addArtefact(ProductHandlerArtefactHandler.TYPE, newClass)
}
}
}
}
}
We also need a artefact handler implementation (which has to be in Java due to legacy reasons)…
import org.codehaus.groovy.grails.commons.ArtefactHandlerAdapter;
public class ProductHandlerArtefactHandler extends ArtefactHandlerAdapter {
// the name for these artefacts in the application
static public final String TYPE = "ProductHandler";
// the suffix of all product handler classes (i.e. how they are identified as product handlers)
static public final String SUFFIX = "ProductHandler";
public ProductHandlerArtefactHandler() {
super(TYPE, ProductHandlerClass.class, DefaultProductHandlerClass.class, SUFFIX);
}
}
And a ProductHandlerClass interface (again in Java)…
import org.codehaus.groovy.grails.commons.GrailsClass;
public interface ProductHandlerClass extends GrailsClass {}
And a DefaultProductHandlerClass implementation of that interface (again in Java)…
import org.codehaus.groovy.grails.commons.AbstractGrailsClass;
import org.codehaus.groovy.grails.commons.GrailsClassUtils;
public class DefaultProductHandlerClass extends AbstractGrailsClass implements ProductHandlerClass {
public DefaultProductHandlerClass(Class clazz) {
super(clazz, ProductHandlerArtefactHandler.SUFFIX);
}
// This method will get the static property 'key' on the underlying
// ProductHandler class that it represents.
public String getKey() {
Object key = GrailsClassUtils.getStaticPropertyValue(getClazz(), "key");
if (key == null) {
return null;
} else {
return key.toString();
}
}
}
That’s a shotgun intro to the Grails Artefact API classes like GrailsClass and ArtefactHandlerAdapter just covering the stuff we need. Check out the linked to source for deeper detail.
Here is what we have done…
grails-app/productHandlers in the app and pluginsonChange handler that reloads product handler classes when they changeArtefactHandler implementation that specifies what a product handler class isGrailsClass subinterface for product handler classeskey on the underlying class (among other things)Armed with our new artefact, we can now simplify our initial implementation…
// Our registry
import grails.spring.BeanBuilder
class ProductHandlerService {
def grailsApplication // autowired
protected createBeanBuilder() {
new BeanBuilder(grailsApplication.mainContext, grailsApplication.classLoader)
}
protected instantiateHandler(handlerClass, Product product) {
createBeanBuilder().with {
beans {
handler(handlerClass, product: product) {
// autowire the handler so it can use services etc.
it.autowire = true
}
}
createApplicationContext().getBean('handler')
}
}
def getAt(Product product) {
def productHandlerClasses = grailsApplication.productHandlerClasses // a list of DefaultProductHandlerClass
def handlerClass = productHandlerClasses.find { it.key == product.handlerKey } // find the one with the matching key
instantiateHandler(handlerClass, product)
}
}
// Example Handler (in grails-app/productHandlers dir)
class OnlyOnTuesdayProductHandler implements ProductHandler {
static key = 'onlyOnTuesday'
Product product
boolean isCanBeSold() {
new GregorianCalendar().get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY
}
}
Each of our product handler classes must specify a key, that products use to link themselves to a particular handler implementation. You could do away with this, and infer the key from the class name quite easily.
class ProductHandlerService {
// …snip…
def getAt(Product product) {
def handlerClass = grailsApplication.getProductHandlerClass(product.handlerKey)
instantiateHandler(handlerClass, product)
}
}
The grailsApplication.getProductHandlerClass() method given the value "onlyOnTuesday" would return the OnlyOnTuesdayProductHandler class object.
In this particular case I personally wouldn’t do this as every time I renamed a product handler class I would have to update the products that use that handler in the DB, but other situations may not have this issue.
All product handler classes are now reloadable, which would obviously be a substantial productivity boost, without all that much work on our part. This approach could be used for any kind of concept or set of classes in your application that don’t fit into the standard controller, service, taglib etc. pattern.
The Artefact API can seem a bit confusing if you don’t take into consideration that this was the heart of Grails in the early days. It’s still there and is used by a great many plugins (e.g. grails-quartz) as well as being used extensively internally in Grails, but it doesn’t quite have the same role that it used to.
Hopefully this has shown you how you can, and why you might want to, use the artefact API internally in your applications.
Posted: Jun 1st, 2010 @ 10:42 pm