October 2007

Go easy with specifying behavior, man

RSpec’s DSL is so hip that I recently found myself wanting that same simple expressiveness in Java (by the way, there’s nothing stopping someone from using RSpec with Java via JRuby)– in fact, what I want is a simple framework that facilitates letting non developers specify behavior. For instance, taking a terribly simple (yet hip) example, imagine (again) a queue data structure. If you were to break it down into a simple narrative, you may end up with something like this:

A queue’s basic behavior can be descirbed as:

it:

  • should throw an exception if null is enqueued
  • should throw an exception if there isn’t anything to dequeue and dequeue is called
  • should dequeue first item enqueued
  • should dequeue items in same order as enqueued

    In a perfect world, I could run this file as is (also, in a perfect world, disco music would be the only thing heard on the radio, in elevators, in cafes, and at parties). Given that I’m close to having my wish with disco music, I figured I’d try my luck with running the file as well. Well, maybe not running the file as is, but trying to get close.

    I started by defining a DSL (backed by a Groovy builder) that looked something like this:

    def specification = new SpecificationBuilder();
    
    specification.QueueBehavior{
    
    before("each":new Queue()){}
    
    "should dequeue first item enqueued"{
      when(enqueue:5){
       ensure(dequeue:51)
      }
     }
    
    "should raise an exception if null is enqueued"{
      when(enqueue:null){
       ensure(Exception:RuntimeException.class)
      }
     }
    
    "should dequeue items in reverse order when enqueue is called"{
      when(enqueue:[5, 7, 9]){
       ensure(dequeue:[5,7,9])
      }
     }
    }

    But, I quickly discovered this particular format was somewhat limiting given the behavior desired in the maps created in the when and ensure elements. For instance, the last behavior (the one labeled "should dequeue items in reverse order when enqueue is called" is ambiguous– what I’m trying to convey is multiple method invocations of enqueue, but it could also mean invoke the enqueue method with three parameters). The SpecificationBuilder class was also becoming quite complex as I had to deal with dynamic method invocation and a lot of parsing.

    Nevertheless, the intent is there in the above code– note, the code doesn’t assume too much knowledge of the underlying object whose behavior is being specified– simple Strings are used instead of method invocations. The non developer pipe dream does break down a bit though. In my case, they’d have to know about RuntimeException exceptions, for example.

    By the way, if you haven’t already done so, check out GSpec– this is a well done framework and I’m not here to rewrite it; however, its groovy author stated that GSpec is “still mostly concept”– so I figure that gives me some liberty to explore some of my concepts. In doing so, I have a deep appreciation for what he’s already accomplished (plus, Cliff is one hip dude, man).

    Also, I wanted to make use of JBehave, which my first attempt above did do underneath the covers. Feeling somewhat frustrated with my efforts in trying to make something interesting, I turned to two incredibly smart guys (who know are also groovy about Groovy) at a recent conference: Venkat Subramaniam and Jeff Brown. These guys are superstars who can provide a lot of information quickly– I made sure to listen anytime one of them opened their mouth, baby.

    Sitting down with these two copasetic cats on Saturday evening yielded something quite interesting. Rather than building a DSL via Groovy’s builders, we set off, under Venkat’s advice, in creating an internal DSL using plain old Groovy. We modeled it after RSpec and used the venerable Queue example as a baseline. After some coding, here and there, we ended up with this:

    import org.disco.bdd.Queue
    queue = new Queue()           
    
    it "should dequeue gives item just enqueued", {
     queue.enqueue(2)
     ensureThat(queue.dequeue(), eq(2))
    }
    
    it "should throw an exception when null is enqueued", {
     ensureThrows(RuntimeException.class){
      queue.enqueue(null)
     }
    }
    
    it "should dequeue items in same order enqueued", {
     [1..5].each{ val ->
      queue.enqueue(val)
     }
     [1..5].each{ val ->
      ensureThat(queue.dequeue(), eq(val))
     }
    }

    Notice that this Groovy script makes use of JBehave’s Ensure library (it even uses some newly created methods like ensureThrows, which obviates JBehave’s Block type). This means that everything you can do in JBehave is at your fingertips when defining these disco behaviors.

    Running this script to keep on truckin’ is easy too. I purposely created a Java based runner so as to make this “idea” framework palpable to a wider audience. Accordingly, specification authors don’t really even need to know that the specification script is Groovy.

    Running this script is as easy as typing:

    ag$ java org.disco.bdd.SpecificationRunner ./src/groovy/org/disco/bdd/QueueSpecification.groovy

    The first argument to the runner is the actual specification, man. This concept framework is by no means totally in the groove– for instance, reporting mechanisms are not present; however, the base is finished (thanks to both Jeff and Venkat). Incidentally, the plumbing of this framework is quite cool as it makes use of Closure delegates quite elegantly (many thanks to Jeff for this suggestion).

    While I still can’t run a hip text file narrative as written above in Java, this specification DSL using Groovy and Java proved to be fun to write and, in my opinion, makes it easier to write a behavior than the more fuzz style Java-JBehave way. Can you dig it, man?

    boo! Java and .NET got scarier

    This is totally mind-blowing, baby: via boojay (an extension to boo, which is a hip alternate language, based on Python, for the .NET platform) you can produce valid Java byte code. To my knowledge, this is a first– via an alternate language running on one platform, you can produce valid code for another target platform (i.e. .NET -> Java).

    For instance, the author of boojay has already demonstrated how to create an Eclipse plug-in in boojay. Of course, there are plenty of copasetic languages for the JVM that produce Java byte code– Groovy, JRuby, Jython; however, these languages can’t (directly) produce valid byte code for the CLR. Is anyone up to this (oh so spooktacular, baby!!) challenge, man?

    If it’s your bag and you want more information on Boo, check out:

    The weekly bag– Oct 26

    Keep on truckin’ man:

    Lastly, if you’re local to the Washington, DC area, you’ll want to join me at Stelligent’s TDD Horror stories event on Oct 30th.

    This podcast doesn’t stink, man

    I recently had a copasetic conversation with Alberto Savoia regarding the hip CRAP metric– my parents would be appalled with our language (I think the word in question is used at least 135 times); however, we had a good time discussing the efficacy of the metric, its future, and of course, its malodorously applied name.

    In short, the CRAP metric effectively marries code coverage with cyclomatic complexity and an effort to delineate risk associated with change. Have a listen (courtesy of JavaWorld) and stay tuned for more podcasts, baby!

    A tell-all night of TDD

    A wicked (i.e. terrifyingly hip) evening of TDD (that’s Test Driven Development, man) horror stories is taking place on Oct 30th in Reston, Va. I can only think of one other thing that could possibly be more fun (that’s disco dancing, man) so if you:

    • are local to the Washington DC area
    • aren’t booked with disco dancing that evening
    • have something to say about TDD, BDD, ADD
    • enjoy knocking back some fine wine

    then you should plan on attending– I’ll see you there (I’ll be the one in shiny clinging Lycra stretch disco pants in hot strident shiny colours with a stretch sequin bandeau shirt, baby)!

    The weekly bag– Oct 19

    On time this time:

    Forget quality, man, give me speed

    At a recent copasetic conference, I had the pleasure of being a member of a panel discussion moderated by one of our industry’s hippest dudes, Ted Neward, where he posed a question something like this:

    Imagine a developer coming up to a manager/CTO/CIO and asking if they could create the next version of the company’s application with Haskell (or some other hip language/tool/framework)– what should the manager say? What should the manager ask or look for when it comes to all these neat-o options?

    There are, of course, a few answers to this question; however, my answer to this is simple– speed.

    If [insert your buzz word here] can produce working features with an acceptable level of quality (meaning that one can maintain it) faster than [insert establishment tool/framework/language] then the answer is yes. Note, I’ve stressed the notion of quality and thus maintainability, but it’s secondary– speed is everything in a competitive market.

    Think about for a second, man. Why has Hibernate essentially dethroned EJB to become the king of Java persistence? Is it because Hibernate is better? Hibernate is arguably “better” than EJB, but the truth is, better rarely wins; plus, better is hard to define. The reason why Hibernate won the battle is because at the time when EJB was the “Enterprise Choice” you could more quickly knock out a working persistence layer with Hibernate. What’s more, Hibernate is easier to test and deploy, making the choice an obvious one. Have you seen the latest EJB spec? Looks a lot like Hibernate, doesn’t it?

    Why has Rails obtained so much tripping attention? Is it because Ruby is a better language than Java? If you’ve ever had the pleasure of writing Ruby code, you’ll probably say yes; however, once again, better doesn’t win over crowds– if so, we’d have all been programming in Ruby 10 years ago. The reason why Rails is so hip is because you can knock out a working web site in short order. Try that with Struts. If you’ve ever developed a Struts application (based upon recent polls, that’s just about everyone), frameworks like Rails (and Grails for that matter) are a breath of fresh air. Not only do Rails and Grails enable rapid turn around of features, they do it with tests in mind– every time you generate some artifact in these frameworks, a test skeleton is also generated (it’s up to you to actually fill it in) but a large part of the effort has been taken care of.

    Why is Agile hip these days? Is it because Agile is easy to adopt as a process? (If you answered yes to that last question, you’re probably doing something wrong.) Easy isn’t what’s selling Agile– heck, Waterfall is a much easier process to adopt, believe me, man. No, the reason why Agile sells is because Agile methodologies facilitate speedy feature development. And, remember, Agile methodologies absolutely stress quality– TDD and CI, are, for example, the brainchildren of Agilests.

    Some will argue that it is a safer choice, to say, develop an application with Struts, Tapestry, etc rather than Rails or Grails because there is a larger base of talent that knows the established “standard”– this is certainly true in the beginning for early adopters, but as we’ve seen time and time again in our industry, the tool that produces working code quickly eventually becomes king. How many people do you know have worked with EJB? How many have worked with Hibernate? I’m willing the bet the answers to those questions can be swapped depending on when you asked them (and how long that person’s been in the industry!). How’s that for an Acid flashback, baby?

    Besides, the safe choice is rather short-sighted; in fact, the safe choice may end up costing a lot of money in the distant future– because it’s their bag, COBOL programmers will command high dollars in the near future. The opposite is also true– bet too early on a technology and you’ll pay out the nose as well– bill rates for Rails programmers appears to be quite nice these days. It’ll level off, albeit slowly.

    Speed without quality kills, but speed with quality sells, baby. Frame your answer (or for that matter, question, request, etc) around speed and people will listen– frame it around features or worse, quality, and prepare to meet blank stares. Dig it?

    The weekly bag– Oct 12

    Enjoy:

    The weekly bag– Oct 5

    Read on with pleasure, baby:

    The weekly bag– September 28

    It’s not too late, man:

    Don’t forget to participate in the highly scientific NUnit poll, baby! So far, the results aren’t too surprising.