Welcome to Giant Robots Smashing Into Other Giant Robots — a weblog about development, business, design and technology — written by thoughtbot.
Introducing the Shoulda Testing Plugin
So we’ve been hinting for some time now that we were going to tidy up the testing helpers we use here, and that’s just what we’ve done.
Update: Added the Why? section below to address rSpec & Test::Spec
Introducing Shoulda!
We had a very hard time coming up with a name for this plugin, mostly because of its somewhat eclectic nature. It does three main things:
Contexts
Shoulda defines context and should blocks:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class UserTest < Test::Unit::TestCase def setup # Normal setup code end def test_can_have_normal_tests # Normal test here end context "a User instance" do setup do @user = User.find(:first) end should "return its full name" assert_equal 'John Doe', @user.full_name end end end |
This is very much like the rSpec way of doing things, but they can be used along-side normal test method definitions. Also, these context blocks can be nested.
Macros
Shoulda also attempts to collect common test patterns into test macros:
1 2 3 4 5 6 7 8 9 10 11 12 |
class UserTest < Test::Unit::TestCase should_require_attributes :name, :phone_number should_not_allow_values_for :phone_number, "abcd", "1234" should_allow_values_for :phone_number, "(123) 456-7890" should_protect_attributes :password should_have_one :profile should_have_many :dogs should_have_many :messes, :through => :dogs should_belong_to :lover end |
Helpers
Finally, Shoulda adds a few basic-but-useful utility methods and assertions:
1 2 3 4 5 6 7 8 9 |
assert_difference(User, :count, 1) { User.create } assert_difference(User.packages, :size, 3, true) do User.add_three_packages end assert_contains(['a', '1'], /\d/) assert_same_elements([:a, :b, :c], [:c, :a, :b]) |
Why not rSpec or Test::Unit
A lot of people are going to be wondering why we didn’t just go with one of the many new BDD style testing frameworks that are out there, like Simply BDD, Test::Spec, or the wildly popular rSpec. I don’t want to minimize the work that’s been done on these very cool pieces of software – in fact, Shoulda would never have been written without their example to lead us. But there were some parts of the rest of the plugins that we just didn’t feel right about.
I wrote another post, specifically about rSpec, but here are the major points (most of which apply to all of the plugins):
contextdefined on Kernel, andshoulddefined on Object – This can make it very hard to extend the framework, and honestly just feels wrong. I can imagine that there would be method definition conflicts between the testing framework and the code being tested. I could be paranoid here, but I didn’t want to find out for sure months down the line.- Extendibility – I think the real value of this testing plugin is in the focused testing macros, which can test large chunks of common code in a single line. The issue above made these kinds of macros hard to write in the other testing frameworks.
- Mocking framework built-in – soon rSpec won’t suffer from this as much as it does now, but I still don’t like the idea of the testing framework and mocking framework being so interlocked.
lambda {}.should.differ(Blog, :count, 1)– This is purely a matter of taste, but we really didn’t see value in the ‘x.should y’ syntax over the ‘assert’ syntax.- Compatibility – This one is rSpec specific. As much as I like the format of the rSpec output, it can cause problems with automated programs that are expecting Test::Unit output. Also, having to run both ‘rake spec; rake test’ to see all of your tests pass seems like an unnecessary annoyance.
Docs & Installation
Full RDocs are available here, and the official Shoulda page is here.
We’re having some troubles with our plugin repository working withscript/plugin at the moment, so svn access will have to suffice:
1 2 |
svn ls http://svn.thoughtbot.com/plugins/shoulda/tags/ svn export http://svn.thoughtbot.com/plugins/shoulda/tags/rel-2.0.4 vendor/plugins/shoulda |
About this entry
You're reading an entry on GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS, the company weblog of thoughtbot, inc.
- Author:
- Tammer Saleh
- Published:
- April 6th 03:01 PM
- Updated:
- April 8th 10:33 AM
- Sections:
- Development Technology
thoughtbot is hiring
We are hiring web developers and web designers in both Boston and New York, NY.
What are we up to?
We built Shoulda, an eclectic set of additions to Test::Unit; Paperclip to manage uploaded files without hassle; Jester, a REST/ActiveResource client library written in Javascript, and Squirrel, an enhancement for ActiveRecord's find syntax; — amongst some other projects.

Chad (President) and Jon (CTO) co-authored a technical book titled Pro Active Record: Databases with Ruby and Rails, which explores the ins and outs of the ActiveRecord ruby library. You can buy it today at Amazon.com.
About thoughtbot, inc.
We are a small web application development consulting business, with offices in Boston, MA and New York, NY. If you're looking to find a team for your next web development project or your new web application — get in touch.
7 comments
Jump to comment form