Archive

Archive for October, 2008

Falling in Love with DSLs

October 29th, 2008

We were recently given a free day at work to hack on a project that was outside the realm of our normal responsibilities, yet could still be beneficial to the company. We were encouraged to be creative, explore ideas that interested us, and see if we could come up with something to demo at the end of the day.

Service level testing, or functional testing, has been a hot topic at work recently. It’s no secret that we have a very large SOA at Orbitz, powered by Jini. Services, calling services, calling services…you get the picture. Historically, we have not been the best at automating the testing of these services. That is beginning to change. About two years ago, the team I work on developed a test tool that allows us to interact with our services at a very high level, keeping us out of the nitty-gritty details when invoking a service. It’s a command line based tool with a very simple, intuitive syntax. All of the details are accessible if we need them, but more often than not they just get in the way. In fact, we enjoyed working at this level of abstraction so much, that I wrote a functional test framework (named jwoodunit by my co-workers) that drove service level tests against our services, which were written in this same “language”. It allowed us to pump out service level tests is very short order that were easy to read, and easy to maintain. It has only just occurred to me that what we had created was really a Domain Specific Language (DSL).

We have a fairly large quality assurance team that is made up mostly non-developers. Most of the testing that is done is manual, or driven by an automation tool similar to Selenium. The problem is that the manual testing is slow and not reliable, and tools like Selenium tend to be brittle, since they are based on the layout of the HTML page. It also prevents you from testing any service that is not directly accessible through the web application. So, for my project, I wanted to see if I could take my team’s DSL, clean it up even more (it is still very “programmy”), and give it to our quality assurance team so that they could test our services in a more reliable fashion.

What I ended up with was a very high level, English like DSL that I call Trastel (Travel Service Testing Language). Trastel is implemented in Ruby. In fact, it’s safe to say that Trastel is Ruby. I didn’t implement a new language. I simply took advantage of Ruby’s fantastic meta programming capabilities to extend the language with functionality that is needed by the tests. A example test is worth 1000 words:

search.flights.on("orbitz").where(
   :origin => "ORD",
   :destination => "LAX",
   :departure_date => "2008/12/10",
   :return_date => "2008/12/15"
)

verify_at_least_one_result

foreach_result do
  verify_equal "ORD", origin
end

This does exactly what you’d expect. It searches flights on Orbitz, flying from Chicago’s O’Hare airport to Los Angeles International Airport on 2008/12/10, returning on 2008/12/15. We then verify at least one result came back, and that the origin of each flight is O’Hare. That’s it.

Implementing this test in Ruby was a breeze. Since everything is an object in Ruby, dynamically adding methods to the Object class gives us the ability to create pseudo-keywords, like “search”, and “foreach_result”. Trastel also sets an attribute named @response on the test, so the code that implements the verify methods can just check that, instead of having to specify that your checking the response of the service call. foreach_result will iterate over the @response if it is an array, yielding to the specified code block for each item in that array…giving us an easy way to check each element. The last bit of magic surrounds the “origin” method. “origin” isn’t a method on object. It’s a method on the the type contained in the @response. Thanks to Ruby’s method_missing method, I can forward that method call onto the object in the @response for it to tell me what origin means. Nice and easy.

Another great thing about Trastel is that it sucks in Active Support. Active Support brings with it a wealth of extensions to the core ruby classes, letting us do something like this:

search.flights.on("orbitz").where(
   :origin => "ORD",
   :destination => "LAX",
   :departure_date => 4.weeks.from_now,
   :return_date => 6.weeks.from_now
)

We still do all of the heavy lifting (creation of the service request, execution of the remote service, etc) in Java, using JRuby to get the Ruby code to play nice with the Java code. But, the DSL serves as an excellent means to collect the data needed to drive the test, call the Java code to invoke the service with that data, and verify the data in the response matches what was expected. It successfully keeps the person writing the test from having to know anything about actually invoking the service. Writing tests at this level of abstraction also shields us from the majority of service API changes that may come our way.

With all of the benefits that I can already see with this still very immature DSL, I’m kicking myself for not considering DSLs more seriously in the past. They have been around quite some time, and have had many well know developers singing their praises. I’m looking to see what other problems I’m currently facing that could be solved a little easier by letting me code a little closer to the domain. Had I know that it would be this simple, maybe I would have tried it a long time ago.

Software , ,

No Firewire Port in New Macbooks? Really?

October 14th, 2008

Wow, this sucks. I was seriously considering picking up a Macbook for my next laptop. Although I’m primarily an Ubuntu Linux user, OS X is becoming quite popular as a development platform. Plus, the hardware in the Macbooks is a big step up from what I’m currently working with. I was thinking a dual boot setup with Ubuntu and OS X on a Macbook would be perfect.

What was really making me consider picking up a Macbook was iLife, and specifically, iMovie. I’ve heard great things about iMovie. Supposedly, it just works, and it’s really easy to get it to do what you want it to do. Linux has no all-in-one video editing package. Just a bunch of stand alone applications that you can piece together to get the whole picture, but that’s too much work for yours truly. And, the Windows ones I’ve tried I usually end up fighting with to get them to do what I want. So, I was really leaning towards the Mac.

But, this is a deal breaker. My miniDV camcorder will not transfer the higher resolution video over USB. If you want the good stuff, you have to use the firewire port on the camcorder. And, I would like the videos of my kids in high resolution thank you very much. It creates a much better end result to blackmail them with when they’re older and don’t like me anymore.

Sure the Macbook Pros have a firewire port. But you know what else they have? A price tag that’s $700 more than the Macbook.

Shortly after Apple’s announcement today, I was already able to find disgruntled folks like myself on the web via Google. I can only hope that Apple fixes this mistake and puts a firewire port back on the Macbook.. Until then, no Macbook for me.

Tech Industry , ,

Diners Club Webapp Has Been Released

October 14th, 2008

I finally got around to cleaning up and publishing the code for the Diners Club web application. Like everything else I release, I’m not sure who will actually use it. But, I find that the whole exercise of releasing your code is beneficial to you and your code. So, it’s worth the effort. It’s available via the MIT license, so have at it.

Kind of a funny side note about this project. I recently found out that a couple of co-workers of mine spend some of their spare time working on Planypus, which is a site for making plans with your friends. Sounds familiar! I was talking to them, and it turns out that Planypus started the exact same way that the Diners Club webapp started, as just a way to organize dinner outings with friends. They however took it to the next level and threw a business plan around it. I’m just not that business savvy I guess :)

Software , , ,