Recently at work we've been having a bit of an argument over the proper way to structure a spec while doing Behavior Driven Development.
I'm going to illustrate a couple of patterns that have emerged using the simple example of a sword that should tell you if it is sharp or not, depending on whether it is new or used.
One camp at my current job, likes to use what I'm calling the Inside-Out Pattern for writing specs. This group likes to start with the method name and then define behavior for it. An example of this is shown here (in RSpec syntax):
describe "sharp?" do it "should tell you if it is sharp or not" do Sword.new(:status => 'new').sharp?.should == true Sword.new(:status => 'used').sharp?.should == false end end
Their argument for this pattern is that all of the code for that method stays in one place, so it's easy to see if you've covered everything in that method.
The argument against this is that your specs are harder to understand and you can't really do real TDD with this method of development.
The other camp likes to use what I'm calling the Outside-In Pattern. This pattern describes the possible states of the object first, and then describes what the object should do in each state:
describe "A new sword" do before(:each) do @sword = Sword.new(:status => 'new') end it "should tell us that it is sharp" do @sword.sharp?.should == true end end describe "A used sword" do before(:each) do @sword = Sword.new(:status => 'used') end it "should tell us that it is not sharp" do @sword.sharp?.should == false end end
The argument for this pattern is that it is more descriptive of what the object should do and it helps with TDD.
The argument this is that you get too many descriptions in your spec, and they can get hard to read. Also, the behavior for a single method in a class is spread around the multiple descriptions, so it becomes harder to make sure that all of the behavior of your method is covered.
Most of the specs that we've written so far seem to skew towards one or the other of these options, but there's no consensus on which of them is better yet, so I figured I'd throw it out there and see if anyone has experience one way or the other and which one has worked better.
Please let me know in the comments.
(And yes, before anyone asks, I'm firmly in one of the camps, and yes, I purposely didn't reveal which one here. I'll be talking more about it in a later post.)
Update: My coworker Dustin points out another way of doing specs that rests firmly in the middle of these two views.