Ruby

JRuby gabfest

In keeping with my copasetic conversations with hip people, I recently had the opportunity to chat with my friend Neal Ford regarding JRuby. As anyone who’s met Neal knows, this cat worships Ruby– what’s more, Neal is a super smart dude that lives and breathes Java as well. Accordingly, Neal offers some interesting thoughts on JRuby (and of course, Ruby) such as meta-programming, JRuby’s future, associated tools, and even Groovy.

Have a listen to this copasetic podcast (courtesy of JavaWorld) and stay tuned for more hip chinwagging, baby!

Is BDD TDD done right?

Every once in awhile, in this Age of Aquarius, when I talk with people about Behavior Driven Development (or BDD) they mention that BDD sounds a lot like TDD done right, man. By that, they mean that like TDD, BDD enables you to think in terms of behavior (or tests/validation in TDD speak) up front (or first). The beauty of thinking about these constructs first is that it, in essence, drives development in a much more fluid manner that permits refactoring and collaboration with copasetic domain experts. This style of coding also builds in confidence up front.

Because it’s my bag, I happen to agree with this notion (that BDD is TDD done right) but I find that BDD makes it a whole lot easier because it drops the word “test” in favor of “should”. And, as I’ve found, should rolls off the tongue quite naturally, man. Take the simple example of a queue data structure. Imagine someone has asked you to describe one– maybe you’d say something like this (note that I even left out the hip filler words in your favor, baby):

A queue is a first in first out data structure. It accepts items via an enqueue method and when dequeue is called, the oldest item (the item who was enqueued before everything else) in the queue should be returned. If dequeue is called on an empty queue, an exception should be thrown; plus, enqueue shouldn’t accept null as a value.

Notice how the phrase “should” popped up here and there quite naturally. Via this description, you can easily start to see BDD in action. For example, given the description of the queue, you can start to define behavior from the sentences like “enqueue shouldn’t accept null as a value.” There are a few different BDD frameworks for you to choose from on practically every platform– one of the more innovative ones is RSpec for Ruby. This particular framework has a particularly hip DSL for defining behavior– watch:

I’ll start with an easy behavior to define– an exception should be generated if someone attempts to enqueue null (or nil in hip Ruby terms). RSpec may look strange at first, but once you’re used to it, it looks quite natural (and elegant). First, rather than declaring a class, you use the describe phrase. You can also use a special method named before (the :each means for each specification) that acts like a normal fixture in xUnit terms.

require 'queue'

describe Queue do

  before(:each) do
    @queue = Queue.new
  end

end

Next, you can define behavior via the tripping it phrase.

it "should raise an error if nil is enqueued" do
  lambda { @queue.enqueue(nil) }.should raise_error(RuntimeError)
end 

Note the lambda phrase– it’s a pretty slick mechanism much like a closure. You can imagine that RSpec keeps on truckin’ and takes the phrase @queue.enqueue(nil) and executes it within a try/catch (or rescue claus) checking what kind of error was raised. Of course, running this behavior at this point won’t work– the Queue class doesn’t exist! All I have to do is implement the desired behavior– raise an error if nil is enqueued.

class Queue

  def enqueue(item)
    if item == nil then raise RuntimeError.new("can not enqueue nil")
    else
    end
  end
end

Now I can run it:

aglover$ spec queue_spec.rb
.
Finished in 0.005292 seconds
1 example, 0 failures

The next behavior regards dequeue when nothing has been enqueued.

it "should raise an error if there isn't anything to dequeue and dequeue is called" do
  lambda {@queue.dequeue}.should raise_error(RuntimeError)
end

Implementing this behavior in the Queue class is pretty easy, man:

def dequeue
  raise RuntimeError.new("nothing to dequeue")
end

The next behavior gets to the real meat of a queue– that is, when you enqueue an item (and it is the only item in a queue) when you call dequeue, you should get that item back.

it "should return item enqueued" do
  @queue.enqueue("test")
  @queue.dequeue.should == "test"
end

By coding this behavior, it becomes evident that the Queue needs some backing collection to actually hold items– otherwise the meat of a queue isn’t there. Isn’t cool, by the way, that RSpec (in concert with Ruby’s MOP implementation) allows me to call should on any old object?

def initialize
  @items = []
end

With an internal array (defined in the constructor of the Queue class) now holding the items of the Queue, I can now code the enqueue method to first check for nil– if the item isn’t nil then add it to the array.

def enqueue(item)
 if item == nil then raise RuntimeError.new("can not enqueue nil")
 else @items << item
 end
end

If I run my hip behavior class, it’ll still fail as the behavior method enqueues and then dequeues an item; hence, I need to code dequeue, which I can code per the spec: “when dequeue is called, the oldest item (the item who was enqueued before everything else) in the queue should be returned.”

def dequeue
 if @items.empty? then raise RuntimeError.new("nothing to dequeue")
 else return @items.delete_at(0)
 end
end

Running my behavior now yields a pass. I’d like to add a few more behavior methods just to verify things are kosher though.

it "should dequeue first item added" do
 [1,2,3,4].each{  | val | @queue.enqueue(val)}
 @queue.dequeue.should == 1
end 

The behavior method above adds a few items and ensures that the first one to be dequeued is the oldest that was added. Now that that works, I want one more behavior that ensures that things are dequeued in reverse order– as you can see below, it isn’t too hard to do in Ruby, man!

it "should dequeue items in reverse order" do
 values = [1,2,3,4]
 values.each{  | val | @queue.enqueue(val)}
 values.each{ | val |  @queue.dequeue.should == val }
end 

So is BDD TDD done right? In essence, yes, but hopefully you’ve seen that BDD’s should construct makes the effort of defining behaviors up front quite easy. In fact, because it’s my bag, I think BDD is easier to adopt than strict TDD dogma. Dig it, man?

What’s after Ant?

At a copasetic CITCON session in Dallas recently, Martin Fowler mused on the “future of build languages” and suggested that due to Ant’s inability to be richly expressive (think conditionals, looping, etc) that future build platforms will be modeled as native domain specific languages much like Rake is in the Ruby world (or SCons is in the Python world). Note, Ant is a DSL, but it is expressed in XML not Java, man.

Because it’s my bag, I largely agree with Martin, however, given Ant’s deep penetration within the Java market, compared to Maven (which, I think is one step closer to a Rake-like build platform for Java) I wonder if the Rake model can come to fruition and obtain any reasonable mindshare. Sure, there are hip projects underway like Raven (which combined forces with JRake recently), which does a number of useful things such as compilation, testing, etc, but ultimately, as Ant is the de facto build platform for Java, practically every tool out there bundles an Ant task. If you want to use Raven and would like to generate a report with JavaNCSS, for example, you might have to write some custom Ruby code to fire the JavaNCSS process off. Hopefully, the increased velocity of development on JRuby will alleviate this issue as it appears JRake makes use of Ant tasks.

It seems to me that if a more DSL-like platform is going to gain any mindshare within the Java community, it’ll have to take advantage of the rich infrastructure present within Ant (Maven did this though and hasn’t overtaken Ant by any means). One such project is Groovy’s Gant, which enables you to specify builds via Groovy rather than XML. Groovy provides expressiveness and is native to the JVM; however, given the history of Java build platforms, I suppose Gant’s adoption will lag behind Maven by a long shot, man.

Interestingly, a few individuals suggested that some of the issues associated with Ant were not necessarily related to Ant, but to people’s usage of the tool. This made me remember an excellent article published a number of years ago that largely still holds true: “Top 15 Ant Best Practices.”

Ultimately, Ant is the de facto standard for building Java applications. Like it or not, it works for 90% of those that attempt to employ it. There will be innovative and clearly more flexible build platforms that’ll pop onto the scene, but displacing Ant is much like thinking that Macs or Linux will overtake Windows installations (in the near future). Displacing these kinds of market leaders takes seismic paradigm shifts (like we are currently seeing with Disco music).

What’s after Ant? Well, we’ve seen what’s next: it’s Rake (or Raven or Gant), but for Java, the vast majority of the community doesn’t appear to care. That’s so establishment.

Ruby refactor city

Because I like refactoring and I can not lie, I was quite excited to see that a group of disco Ruby stars have begun writing a Ruby edition of Martin Fowler’s seminal work “Refactoring: Improving the Design of Existing Code“– thus far they’ve published chapter 1, which is much like the original, just with Ruby code instead of Java.

Keep an eye on rubypatterns.com for updates– hopefully at some point they’ll add an RSS feed!

Ruby test categorization techniques

Much like pre-JUnit 4, Ruby’s copasetic Test::Unit framework lacks the easy ability to programmatically delineate a particular test’s grouping. Nevertheless, categorizing tests in Ruby is easy man– either through test case naming or directory segmentation. It also helps to use Ruby’s Rake build platform.

Because it’s my bag, I prefer the directory strategy as it is easier to put into place and maintain. Briefly, the strategy is to place unit tests in a unit test directory, component tests in a component test directory and so on. Running a particular category then becomes a simple job of defining the appropriate task in Rake.

For example, the following hip Rake file runs all unit tests defined in the tests/unit/ directory.

require “rake/testtask”

task :default => [:unit_test]

Rake::TestTask.new(:unit_test) do | tsk |
 tsk.test_files = “tests/unit/**/*Test.rb”
end

Obviously, for component and system tests, two additional dynomite tasks would be defined which reference .rb files in the tests/component and tests/system directories. It’s usually a good idea to define a dependency task which can run all the tests, which is elegantly done in Rake as follows:

task :test_all => [:unit_test, :component_test, :system_test]

For example, running all tests via the command line is as simple as typing:

 $> rake -f acme_rake testall

Applying test categorizations to a test suite will greatly reduce build times as that suite grows– especially if the test suite has a plethora of higher level tests, where the time to run a test becomes extended due to outside dependencies like databases. Dig it?