Archive

Posts Tagged ‘groovy’

Step-by-step selenium tests with page objects, dsl and fun!

September 29, 2010 10 comments

Note: this is a long post!

Not long ago I wrote about functional tests and the page objects pattern in Aqris’ blog. Back then we at Aqris got all very excited about page objects as they were the solution we were looking for to solve our problems on maintaining our functional test code base, which by that time was based on a set of messy helpers that nobody really understood completely.

Before page objects, whenever a developer in our team had to write a test that had to perform an action no other test already performed, he or she would go through that bunch of helpers trying to figure out which one was the helper that should perform such an action. The result of this approach was that the team couldn’t get to a full agreement on what was each helper’s responsibilities. Everybody agreed that the code was not good, but each person had their point of view on why.

We first learned about the pattern here, when reading about WebDriver (now Selenium 2). Page objects came as the solution to separate the different actions our helpers contained in an extremely simple and even obvious way that nobody in our team had previously thought: simply creating a specialized helper for each page of the application.

It is in fact so simple that I still wonder how come we didn’t think of that before… I think that we were too busy trying to figure out how to deal with the helpers we had, and we were too used to have them that way. I guess that’s because the previous project we had worked on (and the first one we had a strong movement towards automated tests with Selenium) was a web app based on only one single page with lots of GWT-based ajax.

Anyway, excuses aside, we started using page objects and it was great! But then other doubts started to come up: how to deal with parts of a page that are common to many pages – for instance a side navigation bar? How to make our tests more readable? Should our page objects use selenium directly? If yes, how to resolve the selenium dependency? Can the page objects just encapsulate the locators for the html elements instead? Should page objects be responsible for the tests assertions too, depending on xUnit’s API, or should they just provide verification methods that would be used by our tests’ code itself?

I think that these are questions that may or may not have a straight correct answer, but here I will write a bit of what worked well for us or for me later on when dealing with that.
To do that I think we can write a test for an imagined scenario.
Let’s try that!

The problem

Let’s say that we have a test case to test the following hypothetical scenario:

We have a hypothetical book store application.
Every page in the application has a navigation bar on the side.
An user goes to our application home page and, by clicking on a link on the navigation bar, she goes to a page to search for books.
On the search books page she fills in a search form, entering “Tolkien” in the author field and “Rings” in the title field, and submits the form.
She is then redirected to a search result page that contains a list of books along with the same search form already filled in with the same search data she had entered – in this case, “Tolkien” in the author field and “Rings” in the title field.

We want to assure that, given our test data, the search result contains the book ‘The Return Of The King’.
We also want to assure that the search form in the result page still has the data she had previously entered.

The code solution after the jump :)

Read more…

Grails: Separating the database access from the domain classes

May 8, 2010 4 comments

Some days ago I started working on my second project involving Groovy & Grails.
Grails is my first contact with server side development with dynamic languages, and, despite some small problems (mostly due to the fact that the framework is still not so mature compared to others out there), I really, really enjoy it.

One of the things that I like is how using Groovy’s dynamic features the framework injects database access technicalities into our domain classes.
The domain is therefore smart enough to retrieve/update its relationships and even to find/update itself, all without the need to pass around repositories dependencies whatsoever, or to force the domain classes to extend any other classes.

But sometimes we need to write HQL (or criterias) ourselves, and then in our first project we ended up having some domain classes quite bloated with custom queries and a lot of other database related operations mixed with pure domain-specific logic operations.

Something like this:

  class Book {
    // properties, mappings, constraints
    // domain methods

    def findAllBooksFromTheSameAuthor() {
      return findAll("some HQL")
    }

    def findSimilarPurchasedBooks() {
      return findAll("some HQL")
    }
  }

This code is just a silly example to illustrate the problem.
Of course we could have used Grails’ dynamic finders for those queries too, but we would be externalizing the internals of our domain class so we like this approach of adding custom query methods better.
One thing we didn’t like though, is that we had many methods like the ones above, mixed with the domain logic and properties.
So we decided to move these methods somewhere else and inject them into our domain classes, like Grails does with its dynamic generic finders.

A very nice way to do it seemed to be using Groovy’s Delegate annotation, having something similar to:

  class Book {
    @Delegate BookQueries bookQueries = new BookQueries(this)

    // properties
    // mappings, constraints, domain methods
  }

  class BookQueries {
    Book book

    BookQueries(Book book) {
      this.book = book
    }

    def findAllBooksFromTheSameAuthor() {
      return Book.findAll("some HQL")
    }

    def findSimilarPurchasedBooks() {
      return Book.findAll("some HQL")
    }
  }

We have to pass the book object to BookQueries because we are gonna need its properties to build our queries.
For instance, we need its author to find all books from the same author.
And using the delegate we can call methods from BookQueries with a Book object:

  book.findSimilarPurchasedBooks()

The only problem with this is that we also had some static methods to first retrieve our objects.
These are queries that are not related to any relationship or similarities between objects, so they are static methods in the Book class:

  static def findBestSellersInMonth() {
    findAll("some HQL")
  }

The problem is that static methods are not delegated.

In our project we decided to scrap the @Delegate for good, move all custom query methods to BookQueries, including the static ones, transform them into closures and inject them manually, one by one, into the Book class during the application BootStrap, using Groovy’s Expando metaclass.

But I didn’t really like this approach.
I think I’d rather keep the @Delegate, and then move the static methods to a BookRepository class:

  class BookRepository {
    def findBestSellersInMonth() {
      return Book.findAll("some HQL")
    }
  }

It might seem as a step backwards.. “why do you need repositories if you have your rich domain that can retrieve itself?”
But the static modifier already tells that these methods don’t belong to our domain *objects*.
They are there to initialize the objects, retrieve them from somewhere (the database).
And, well, isn’t this part of the definition of repositories? =P

Update — May 10th ———————————

Peter Ledbrook suggested using Grails’ named queries (see comments). It looks indeed very nice, but we really wanted to move our queries out of our domain class, to make it more readable and, well, prettier :D

With the named queries we could move a static block containing the static queries to the BooksQueries class and assign this static block to a static nameQueries block in the Book class, and this would import the static queries.

Today I was messing with this a bit more and I realized that I could just inject the static methods into my domain class from inside my delegate itself.
It’s so simple I don’t understand how come I didn’t think about that before :D
So, if you don’t like the repository approach, you can always have something like:

  class Book {
    @Delegate BookQueries bookQueries = new BookQueries(this)
    // all Book properties, constraints, domain methods, etc
  }

  class BookQueries {

    static {
      BookQueries.metaClass.methods.each {
        if (it.static) {
          Book.metaClass.static."$it.name" = owner.&"$it.name"
        }
      }
    }

    Book book

    BookQueries(Book book) {
      this.book = book
    }

    def findAllBooksFromTheSameAuthor() {
      return Book.findAll("some HQL")
    }

    static def findBestSellersInMonth() {
      return Book.findAll("some HQL")
    }
  }

Follow

Get every new post delivered to your Inbox.