[rspec-users] New article on "Listening to Your Specs" up on Ruby Advent 2008
dchelimsky at gmail.com
Tue Dec 16 15:56:45 EST 2008
On Tue, Dec 16, 2008 at 2:51 PM, Ben Mabey <ben at benmabey.com> wrote:
> 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
>> 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
>> 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.)
Oh - in that case, I disagree :) At least w/ including them in example
group docstrings. I think it's just fine and can lead to very readable
returns the top element
removes the top element
returns the top element
does not remove the top element
This is also a nice way to see things from a higher level. If the
"does not remove the top element" example was missing, it'd be obvious
that it was, and might lead you to add that example.
>>> 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
>>> 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
>>> 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).
>>> think the following contrived example would be fine. It clearly shows me
>>> 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"
>>> than "behavior brain". You're thinking "I know we are going to need a
>>> "#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
>>> feel its a smell to get down to the object level when necessary. One of
>>> 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
>>> at the current level. Using object level examples to focus in on
>>> in isolation is a valuable technique. Again, its all about focussing at
>>> right level of granularity.
>>> For ex. part of an 'update profile' feature might involve showing a user
>>> 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
>>> from the outside in might eventually drive me to it so that I can drill
>>> 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
> rspec-users mailing list
> rspec-users at rubyforge.org
More information about the rspec-users