Cucumber: The Latest in Ruby Testing
Testing is a firmly ingrained part of the Ruby culture: you probably ran across Test::Unit not long after you first started writing Ruby code (though it wouldn't be surprising if you ignored it for a while). But it hasn't been a static part of Ruby - we've seen the simple availability of tests evolve into test-driven development (TDD) that in turn gave rise to behavior-driven development (BDD). Along the way, Ruby has spawned a variety of testing tools and frameworks. The latest, Aslak Hellesoy's Cucumber, is the latest addition to the RSpec family of tools.
Cucumber is designed to allow you to execute feature documentation written in plain text (often known as "stories"). I've been experimenting with it as a replacement for integration tests in Rails. With Cucumber, you can write tests that look like this:
Scenario: See all vendors
Given I am logged in as a user in the administrator role
And There are 3 vendors
When I go to the manage vendors page
Then I should see the first 3 vendor names
With Cucumber, that it an executable specification that you can discuss with the customer and then use to verify the correct behavior of tests. Behind the scenes, you make it work by writing "steps," which are regex matchers that execute Ruby code. Here's one of the steps for that scenario:
Given /there are (d+) vendors/i do |n| Vendor.transaction do Vendor.destroy_all n.to_i.times do |n| Factory.create(:vendor, :business_name => "Vendor #{n}") end end end
Ideally, you'll do this all in true BDD fashion: write the Cucumber features first, watch them fail, implement code to make them pass (with lower-level tests written with RSpec or Test::Unit), and repeat.
Cucumber is under rapid development, but it's already a useful part of my testing toolbox. In addition to integrating with RSpec and Rails, it works with Merb, Sinatra, and the Webrat web-testing framework (as well as, of course, pure Ruby projects). It also has translations into 20 languages and the ability to run FIT-style tabular tests. If you're looking for a higher level of abstraction in your tests, it's definitely worth checking out.
Supported by: ActionGear is a menu-bar app for task management on your Mac. It's lightweight, quick, and helps you get stuff done. Try it out for free.
November 19, 2008 at 7:47 pm
Brandon Keepers gave a talk on Cucumber at the Great Lakes Ruby Bash 2008. In case anyone is interested his slides are available online at:
http://www.slideshare.net/bkeepers/behavior-driven-development-with-cucumber-presentation
November 19, 2008 at 8:36 pm
Awesome, thanks Daniel!
November 19, 2008 at 9:03 pm
"you probably ran across Test::Unit not long after you first started writing Ruby code (though it wouldn't be surprising if you ignored it for a while)"
Then there are those of us who've been TDDing for 10 years and came to Ruby and RoR precisely *because* of its support for testing.
November 19, 2008 at 9:28 pm
Does cucumber do the same thing as http://github.com/foeken/webrat_story_steps/ ? Only without the selenium integration? Or am I missing the point here?
November 19, 2008 at 10:21 pm
I came across a great write up of the nitty gritty of getting started on "Craig's Site":http://barkingiguana.com/2008/11/16/writing-a-story-why-when-where-who-what-how-and-a-bunch-of-other-questions-and-answers
November 19, 2008 at 11:14 pm
COBOL, is that you? :)
I am a bit apprehensive of this direction.. but it would not be the first time I turned out to be wrong.
November 20, 2008 at 12:36 am
Cucumber also works well with test/spec and test::unit as well.
November 20, 2008 at 9:16 pm
It seems to work well with pretty much any testing framework (I've been using it with matchy, as well). It's a shame it has [what seems to be an unnecessary] gem runtime dependency on rspec and that the documentation thus far seems skewed in using it in that way.
November 21, 2008 at 4:28 pm
@rue: No, COBOL had only a few predetermined templates like "ADD x TO y GIVING z". This language lets you write your own templates (and define your own routines to implement the templates). Not even in the same class.
November 21, 2008 at 5:50 pm
My colleague Rahoul has also just posted a step by step intro to using Rspec, Cucumber and Stories...
http://blog.brightbox.co.uk/posts/using-rspec-cucumber-and-user-stories-to-build-our-internal-systems
November 23, 2008 at 5:56 pm
Cucumber no longer depends on RSpec, and I have added an example showing how to use plain Test::Unit assertions inside step definitions.