Code as Art

I figure that as a programmer, I should be aware of the classic literature in the field. Most lists of must-read computer science books include The Mythical Man-Month, a collection of essays by Frederick Brooks. First published in 1975, it presents the author’s views and opinions on the subject of software engineering, as informed by his experiences in managing the deveopment of OS/360 at IBM.

I haven’t gotten through the whole thing yet, but I’ve found it very interesting and informative thus far. There is one section in particular, in the essay called The Tar Pit, which I like. It provides a nice description of the creativeness which is often involved in programming:

As the child delights in his mud pie, so the adult enjoys building things, especially things of his own design. I think this delight must be an image of God’s delight in making things, a delight shown in the distinctness and newness of each leaf and each snowflake…

The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures…

Yet the program construct, unlike the poet’s words, is real in the sense that it moves and works, producing visible outputs separate from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.

It’s a good thing that there are people out there who can verbalize ideas this well. Especially when, like Bach, they sign their work SDGSoli Deo Gloria.

Moving Groovy Forward: G2One

Earlier this month Guillaume Laforge (Groovy project manager), Graeme Rocher (Grails project lead) and Alex Tkachman (former JetBrains COO) announced the creation of G2One, a Groovy/Grails consultancy. I’m a little late to the party, but better late than never: congratulations!

It’s particularly encouraging to see Alex’s name on the list — he must be anticipating very good things if he chose to leave JetBrains in order to pursue this new opportunity. It’s also good to see money being thrown at dynamic languages on the JVM (aside from Sun’s). I think it’s a good harbinger of things to come.

Assertions in HtmlUnit

I’ve been going back through the pros and cons of JWebUnit as part of my research for the HtmlUnit vs Foo series of articles I’m writing. One of JWebUnit’s big draws is the set of easy-to-use assertion methods provided by its base test case class, WebTestCase. HtmlUnit doesn’t provide such a thing, because it doesn’t provide a base test case class.

There has always been something of a trade-off here: use JWebUnit and tie yourself to a specific unit testing framework (JUnit) while benefiting from a more domain-specific set of assertions (assertCookiePresent, assertFormPresent, assertLinkPresent, etc), or fly free with HtmlUnit but perform assertions using only the primitive utility methods provided by your unit testing framework (assertNull, assertNotNull, assertEquals, etc).

However, I’ve long though that it would be nice for HtmlUnit to have the best of both worlds by using an assertion utility class, similar to TestNG’s Assert class. Experiencing the convenience of JWebUnit’s API again has given me the final kick in the pants, and the first version of HtmlUnit’s new WebAssert class is now in SVN. It will be included as part of HtmlUnit 1.14, or you can always grab the latest build here. I’m sure the set of available assertions will grow, but here is the initial list:

  • assertTitleEquals(HtmlPage, String)
  • assertTitleContains(HtmlPage, String)
  • assertTitleMatches(HtmlPage, String)
  • assertElementPresent(HtmlPage, String)
  • assertElementPresentByXPath(HtmlPage, String)
  • assertElementNotPresent(HtmlPage, String)
  • assertElementNotPresentByXPath(HtmlPage, String)
  • assertTextPresent(HtmlPage, String)
  • assertTextPresentInElement(HtmlPage, String, String)
  • assertTextNotPresent(HtmlPage, String)
  • assertTextNotPresentInElement(HtmlPage, String, String)
  • assertLinkPresent(HtmlPage, String)
  • assertLinkNotPresent(HtmlPage, String)
  • assertLinkPresentWithText(HtmlPage, String)
  • assertLinkNotPresentWithText(HtmlPage, String)
  • assertFormPresent(HtmlPage, String)
  • assertFormNotPresent(HtmlPage, String)
  • assertInputPresent(HtmlPage, String)
  • assertInputNotPresent(HtmlPage, String)
  • assertInputContainsValue(HtmlPage, String, String)
  • assertInputDoesNotContainValue(HtmlPage, String, String)

HtmlUnit vs HttpUnit

There’s a lot of misinformation out there regarding web application test tools, so I’ve decided to post a series of short articles comparing some of the open source options available here in Java-land, circa 2007. The first of these articles will focus on HtmlUnit and HttpUnit. Please take my criticism and praise with a grain of salt, as I’m a committer to the HtmlUnit project and thus probably biased. Nevertheless, I will do my best to be objective. I may even overcompensate in the other direction!

Confusion

The HtmlUnit and HttpUnit projects are often confused due to the similarity of their names. And the similarity doesn’t end there: they are both open source projects; they are both 100% Java frameworks, rather than drivers for native browsers like IE or Firefox; and they are both fairly mature projects.

This confusion is compounded by the fact that many test frameworks which once used HttpUnit under the covers have since switched to using HtmlUnit, mainly in order to benefit from its excellent JavaScript support. Examples include JWebUnit, whose FAQ briefly explains the switch, and Canoo WebTest, which switched in 2004 due to JavaScript support issues and an unresponsive development team [1].

HttpUnit

HttpUnit is the granddaddy web app testing framework. Started in the summer of 2000 by Russ Gold [2], it was the first project to focus on this niche area. The project has since stagnated somewhat, with nearly 40% of bugs remaining open, some of them nearly three years old. Its latest maintenance release is about a year and a half old.

The API is fairly low-level, modeling web interactions at something approaching the HTTP request and response level. The following is a slightly modified example from the HttpUnit Cookbook:

WebConversation wc = new WebConversation();
WebResponse resp = wc.getResponse("http://www.google.com/");
WebLink link = resp.getLinkWith("About Google");
link.click();
WebResponse resp2 = wc.getCurrentPage();

As you can see, things center around WebConversations, WebRequests and WebResponses. Unfortunately, any page with a decent amount of JavaScript is likely to break HttpUnit, and you can absolutely forget testing any pages which use third party JavaScript libraries.

Nevertheless, HttpUnit continues to generate 3,000 to 4,000 downloads per month. A good analogy, if I may be allowed a brief subjective comment, is that HttpUnit is to the web app testing world what Struts is to the web app framework world: there are many “better” options out there, but it just won’t go away! ;-)

HtmlUnit

HtmlUnit is itself a fairly old project, having been started by Mike Bowler in early 2002. Mike has since ceased active development, but the project currently boasts 3 or 4 active developers and a total of seven committers (whereas HttpUnit remains a one-man show). It averages about three releases per year, and has seen increased developer activity in the past six months or so, especially in the area of JavaScript support.

HtmlUnit’s API is a bit more high-level than HttpUnit’s, modeling web interaction in terms of the documents and interface elements which the user interacts with:

WebClient wc = new WebClient();
HtmlPage page = (HtmlPage) wc.getPage("http://www.google.com");
HtmlForm form = page.getFormByName("f");
HtmlSubmitInput button = (HtmlSubmitInput) form.getInputByName("btnG");
HtmlPage page2 = (HtmlPage) button.click();

As you can see, the code centers around WebClients, as well as pages, links, forms, buttons, etc. Pages with a modicum of custom JavaScript will probably work when tested with HtmlUnit. Unfortunately, pages which use third party libraries might or might not work when tested via HtmlUnit. As of the current version, Prototype, Script.aculo.us, DWR and jQuery are known to be supported fairly well, Dojo is a bit of an unknown, YUI is known to be unsupported, and GWT is known to work with fairly simple applications. Most of this compatibility has been achieved in the past two or three releases, so obviously things are fairly fluid.

Conclusion

If you’re using HttpUnit for legacy reasons, it’s a fairly solid package, but don’t expect to get much support when you need to report a bug or submit a patch for a new feature. If you’re starting a new project and are trying to decide between these two frameworks, HtmlUnit wins hands down. It has the features, the community and the momentum.

Of course, if you’re considering web application testing tools, you’re probably looking at more than just these two options. Canoo WebTest, TestMaker, JWebUnit, Selenium, WebDriver and JMeter are all likely to be on your list. Depending on your project budget and requirements, Squish and Mercury QTP may also be under consideration. If that’s the case, stay tuned, because I intend to post a series of web app testing framework comparisons in the coming months — all of them involving HtmlUnit, of course!

[1] It’s interesting to note that both Marc Guillemot and I (two HtmlUnit committers) began by using HttpUnit, submitting patches for missing features — but settled on HtmlUnit when the patches were not applied in a timely manner.

[2] The HttpUnit website states that Russ currently works for Oracle, developing the OC4J application server. Coincidentally, this is the production application server we’re using at my day job. Thanks, Russ! :-)

Goodbye Persistence Layer?

A couple of weeks ago a colleague and I were discussing DAOs, and whether or not they could be eliminated in a minimalist approach to application architecture. Specifically, since JPA is essentially a standardization of the persistence layer, do you really need a custom persistence layer to wrap the standard persistence layer?

Coincidentally, InfoQ addressed this same question just a couple of days later, and it appears that a small portion of the JEE blogosphere has debating the issue for some time now. The consensus, which I agree with, is that it really depends on the application. If you have a relatively small domain model, it might be a good idea to forgo custom DAOs.

I’ve been experimenting with this approach in a small application which I’ve been developing as a pet project, and I’ve been very pleased thus far. The only aspect which makes me slightly uncomfortable is the sprinkling of JPAQL which now exists in my service layer. A criteria API similar to the one offered by Hibernate would, in many cases, be a good alternative to JPAQL, and I seem to remember having read somewhere that JPA 2 will include this feature.

So is it time to say goodbye to DAOs? Not at all. Anyone developing an application with more than a dozen domain objects should think long and hard before throwing time-honored best practices overboard.

But there’s a gray area somewhere in the spectrum between “homebrew CD collection tracker application” and “commodity market trading backbone.” As your domain model gets smaller and smaller, your DAOs will start to look more and more anemic, and it’s possible that at a certain point you may say “forget it, I’m going DAOless.” Just know that you’re not alone.

« Previous entries