On Jun 28, 2008, at 8:52 AM, Jim Gay wrote:
On Jun 28, 2008, at 5:32 AM, David Chelimsky wrote:
I'm beginning to regret the validity example, because it is somewhat structural as well. The behaviour is not whether it's valid or not, but rather whether you can save it or not. So scratch the example I gave earlier and think about this:

describe Project do
describe "when trying to save" do
  it "should complain if it has no owner" do
    lambda do
      Project.new(:owner => nil).save!
    end.should raise_error(ActiveRecord::RecordInvalid)
  end
end
end

(Zach Dennis - this nesting structure should make you happy :) )

That make a bit more sense?

Absolutely!

One key aspect of BDD is working Outside-In. I try to start with a story and to drive things down from the view to the model (in Rails). So maybe my story is that as an owner I can edit my projects, but not other people's projects. This is going to naturally lead me towards examples that will implicitly cover the fact that an owner can more than 0 projects without actually specifying that directly.

Trying to wrap my head around how to go about BDD has been difficult and I think I now understand why. Many of the examples I've seen for RSpec have used things like "should be valid" when that doesn't actually describe behavior at all. The first RSpec generated Rails specs that I used had plenty of this

Ugh! You're right. I'm going to review the generators (they were written a lot of water-under-the-bridge-ago).

... but that seems to be more about implementation than behavior, so I've had trouble understanding how to really describe behavior.

Little by little I'm getting it, but I unfortunately don't feel like I have time to go BDD cold turkey. I still do some code first and then spec, but I understand the benefits of BDD and I'm sure I'll get to that point eventually.

Try this as a next step:

* code a little
* comment out your code
* write a small example for a small bit of the commented code
* watch it fail
* uncomment just enough to make it pass
* watch it pass
* repeat the last 4 steps

This is NOT the end-game, but it will give you a feel for the TDD flow. Plus, at some level, we're all usually operating with some knowledge about the code we're going to write. When we're not, it's common practice from old-school-TDD to code a little, throw out the code entirely (not comment it, but actually delete it) and then start w/ examples. The reason we throw it out is the "code a little" phase quite often introduces something we just don't need. In the comment/ uncomment approach, those unnecessary bits tend to stick around because we *think* we need them.

One great promise of TDD is that it encourages less code because we're working against executable examples rather than assumptions about what the code does based on looking at it.

Cheers,
David

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to