[rspec-users] New article on "Listening to Your Specs" up on Ruby Advent 2008
lenny at aps.org
Fri Dec 19 12:02:08 EST 2008
On Dec 16, 2008, at 3:58 PM, Ben Mabey wrote:
> Lenny Marks wrote:
>> On Dec 9, 2008, at 10:40 PM, Avdi Grimm wrote:
>>> I contributed an article on BDD and RSpec to the Ruby Advent
>>> 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 cents.
>> I agree with most of the points in this article, but not so much
>> the part about:
>> 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
>> 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
>> 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
>> 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
> Hey Lenny,
> I agree with a lot of what Avdi said in the article. One big
> exception was the the "Contexts named after methods" section.
> (However, I do agree with the examples named after methods.)
> My argument for having contexts named after methods is simple:
> documentation. It helps me quickly scan example groups to find
> specific examples about how to use the public methods (the API.)
> Maybe we should be using rdoc more but the team I work with has
> adopted this convention and have found that it helps us understand
> how to use objects written by other team members. This convention
> does not work well with all examples however, so we use it on a
> case-by-case basis.
> Another reason why I think I like using method names in contexts is
> because of how I like to develop. Going from the outside-in I
> usually use mocks to discover the interfaces I wish I had. Once I
> finish writing the collaborators I then start on the object's
> implementation. I start by documenting (writing code examples of)
> the cases how the collaborators are already using that method and
> expecting the object to behave from using the object in that way...
> So, I actually find using method names in example groups a very
> natural thing to do that just comes from going outside-in. At
> least in my experience. :) Again, I don't stick to this way for
> organizing all of my examples but I think it has its place and adds
Actually, I got lost in the semantics a bit. I didn't realize his
'Examples named after methods' anti-example was specify
"#flush_and_reset" not 'describe'. Anyway, I too was mainly having a
problem with 'Contexts named after methods' being identified as a
smell for much the same reasons as you site.
Thanks to you and Dave for your responses. I've commented on the
original article with back links to this thread. Hope I didn't
overstep by saying "I think there is some consensus that 'Contexts
named after methods' is not a smell and can even be a natural result
of 'Outside In' coding".
> rspec-users mailing list
> rspec-users at rubyforge.org
More information about the rspec-users