Making Web Tests Readable, Robust and Rapid

Tutorial: Groovy Functional Testing with Geb - Part 6

   

Comparing the Tests

Consider the differences between SimpleLoginSpec and LoginSpec. By using page objects and content definition in LoginSpec, we were able to test the same functionality as SimpleLoginSpec in an incredibly more readable and robust fashion. LoginSpec’s test code almost reads as a plain English description of what the test is doing and expecting. SimpleLoginSpec may test the same behavior, but making sense of the raw selectors is at best difficult and at worst can lead to heaps of wasted development time spent simply trying to figure out what the test is attempting to do. Using a page object model to expose the semantics of the page rather than the implementation details results in tests that can actually serve as application documentation. In many cases, such tests can be more valuable as clear documentation of expected application behavior than they are as regression tests!

I discussed earlier how selectors in SimpleLoginSpec were extremely sensitive to change, resulting in brittle tests that require large amounts of refactoring to correct failures caused by minor disturbances to the markup. Consider the impact of changing the id of the login form from “login-form” to “user-sign-in-form”. LoginSpec would fail, just as SimpleLoginSpec would. Unlike SimpleLoginSpec, however, LoginSpec can be fixed without changing a single line of test code. In fact, the only change needed would be the line in LoginPage that defines the loginForm content:

loginForm { $("#user-sign-in-form") }

Because all of the other content definitions reference loginForm rather than include the form’s id explicitly, no other changes are needed. Certainly, there may be some breaking markup changes that can be a pain to refactor. The page object model, however, ensures that most of that work is encapsulated entirely within the Page class and not within the test code.

The functional tests I’ve presented here only scratch the surface of the gains that are possible using Geb. A well-defined, extensible page object model contributes more than just robust and readable functional tests. Other developers can write their own tests more quickly and concisely by using existing Page classes. Refactoring commonly used page content into Module classes that can be reused across multiple Pages can reduce code duplication. Furthermore, Page objects are still traditional GroovyObjects and can make use of all of the standard object oriented features—inheritance, method definition and so on—to become extremely powerful and reusable testing components. When you start to think of modelling your web pages in the same way you would any other data, your functional tests can reap the same object-oriented programming benefits that you’re used to in your application code.

Conclusions

Any serious web application developer should heed the benefits of automated functional testing. Geb is the most elegant and powerful browser automation tool available today. Proper use of Geb’s Page Object implementation can yield extremely readable and robust functional tests that can both detect regressions and serve as documentation of application behavior. Geb’s expressive content definition DSL and jQuery-ish Navigator API make writing such tests a breeze. If you’re interested in getting started with Geb yourself (and how could you not be?), The Book Of Geb contains all of the information you could hope for and more.

If you still get stuck, fear not—the Geb mailing list is extremely active, responsive and friendly. You owe it to yourself to explore everything Geb has to offer, because it’s the tool your web application deserves. With Geb, writing clear, powerful and maintainable functional tests has never been easier.

Ellery Crane

What do you think?

JAX Magazine - 2014 - 05 Exclucively for iPad users JAX Magazine on Android

Comments

Latest opinions