[rspec-users] New article on "Listening to Your Specs" up on Ruby Advent 2008
ben at benmabey.com
Tue Dec 16 15:51:06 EST 2008
David Chelimsky wrote:
> On Tue, Dec 16, 2008 at 2:01 PM, Lenny Marks <lenny at aps.org> wrote:
>> On Dec 9, 2008, at 10:40 PM, Avdi Grimm wrote:
>>> I contributed an article on BDD and RSpec to the Ruby Advent Calendar
>>> 2008, going over some of the rules I've collected for interpreting
>>> what your specs say about your design. It can be found here:
>> I'm curious where others stand on the topic of object level specs with
>> describe blocks named after methods. I posted the comment below with my 2
> I posted on the blog, but essentially I don't think you guys are at
> odds. Avdi is talking about examples named for methods:
> it "#method_name" do
> not example groups (which I think are fine, and I think Avdi does as well):
> describe SomeObject do
> describe "#method_name" do
> context "some state" do
> it "does something" do
> Here there is a group named #method_name, but there are potentially
> multiple examples of how that object responds to that message in
> different states.
Actually, Avdi did argue against both cases... (Method names in example
groups and examples.)
>> I agree with most of the points in this article, but not so much the part
>> Contexts named after methods
>> A describe block should encapsulate a particular scenario: an object or set
>> of objects in a specific configuration. If objects are nouns, and methods
>> are verbs, then contexts should describe nouns, not verbs.
>> I think this is more or less what Aslak was saying but I wanted to get more
>> specific. IMO, using rspec to spec behavior at the object/unit level, it
>> often makes perfect sense to describe the behavior of the verbs(methods). I
>> think the following contrived example would be fine. It clearly shows me the
>> what this method does and what the scenarios it handles are.
>> describe Account, "#debit" #maybe 'debiting' is better, but #debit is
>> actually more descriptive of the API which is the level I'm at here.
>> describe "with sufficient funds"
>> it "should reduce balance by debited amount"
>> it "should ..."
>> describe "with insufficient funds"
>> it "should raise an InsufficentFundsError"
>> it "should ...
>> Actually in the above example I probably would have started with the
>> following and only grouped into nested contexts when I started repeating
>> myself(e.g. repetition of 'when balance is sufficient')
>> describe Account, "#debit"
>> it "should reduce balance by debited amount when balance is sufficient"
>> it "should raise an InsufficentFundsError when insufficient"
>> Examples named after methods
>> There is rarely a one-to-one relationship between desired behaviors and
>> methods on an object. When you name an example after the method it tests,
>> it's a clue that you have started to think in "implementation brain" rather
>> than "behavior brain". You're thinking "I know we are going to need a method
>> "#foo" which does such-and-so, so I'll just start spec-ing it now…". Step
>> back, and think about the behavior you are really interested in. You may
>> find it changes how you write examples. Or, you may find that you didn't
>> need that method at all.
>> I don't agree much with the above either. I think this the difference
>> between speccing behavior at the application level vs. object level. I don't
>> feel its a smell to get down to the object level when necessary. One of the
>> benefits of BDD at the object/code level(as opposed to feature level) is
>> helping to flesh out the API(what classes, what methods, what
>> inputs/outputs) that implements a feature. New classes and methods spring
>> into existence as I realize that there are details(a new responsibility)
>> that I eventually want to drill into but would only be distracting or messy
>> at the current level. Using object level examples to focus in on something
>> in isolation is a valuable technique. Again, its all about focussing at the
>> right level of granularity.
>> For ex. part of an 'update profile' feature might involve showing a user an
>> error message if he/she submits invalid data. Now I wouldn't start off
>> thinking, I'm going to need a User class with a validate method, but going
>> from the outside in might eventually drive me to it so that I can drill into
>> all the details of what constitutes valid data directly/in isolation,
>> without being mixed in with a bunch of other stuff or extra
>> rspec-users mailing list
>> rspec-users at rubyforge.org
> rspec-users mailing list
> rspec-users at rubyforge.org
More information about the rspec-users