Forum: RSpec New article on "Listening to Your Specs" up on Ruby Advent 2008

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Avdi G. (Guest)
on 2008-12-10 05:40
(Received via mailing list)
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:
http://advent2008.hackruby.com/past/2008/12/10/lis...

--
Avdi

Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com
Bart Z. (Guest)
on 2008-12-11 09:07
(Received via mailing list)
On 10 dec 2008, at 04:40, Avdi G. 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:
> http://advent2008.hackruby.com/past/2008/12/10/
> listening_to_your_specs/

Great article!
Found a lot of good practices here, especially the @it example.

thanks a bunch,
bartz
Lenny M. (Guest)
on 2008-12-16 22:16
(Received via mailing list)
On Dec 9, 2008, at 10:40 PM, Avdi G. 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:
> http://advent2008.hackruby.com/past/2008/12/10/
> listening_to_your_specs/
>
> --
> Avdi
>
>

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.

-lenny

I agree with most of the points in this article, but not so much the
part about:

<quote>
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.
</quote>

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"
..

<quote>
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.
</quote>

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 setup.
David C. (Guest)
on 2008-12-16 22:46
(Received via mailing list)
On Tue, Dec 16, 2008 at 2:01 PM, Lenny M. <removed_email_address@domain.invalid> 
wrote:
>>
>>
>
> 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 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.

Cheers,
David
Pat M. (Guest)
on 2008-12-16 22:49
(Received via mailing list)
Lenny M. <removed_email_address@domain.invalid> writes:

>>
>
> unit level, it often makes perfect sense to describe the behavior of
> 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"
> ..

Yes.  This style of specification has a lot of documentation value.  You
look at the RDoc for a method that looks like what you want, and then
you can look at the spec to get concrete examples of how it's used.

A friend of mine has toyed with the idea of putting the specs directly
in the RDoc, or generating RDoc from the specs.  Seems promising.


> you write examples. Or, you may find that you didn’t need that method
> at all.
> </quote>

And when you do know that you need the method?  Like if you had driven
it from working outside-in.

I don't like a lot of the stuff that Avdi writes.  He made some pretty
good points in this article though, but I would hope that nobody holds
it up as a canonical description of BDD (I don't think there really
is/should be one, but if there were, it'd have to be Dan's stuff imo).

Pat
Ben M. (Guest)
on 2008-12-16 22:54
(Received via mailing list)
David C. wrote:
>>> --
> odds. Avdi is talking about examples named for methods:
> 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.)
David C. (Guest)
on 2008-12-16 22:58
(Received via mailing list)
On Tue, Dec 16, 2008 at 2:47 PM, Pat M. <removed_email_address@domain.invalid> 
wrote:
>>> --
>> I agree with most of the points in this article, but not so much the
>> I think this is more or less what Aslak was saying but I wanted to
>> it "should ..."
>> it "should raise an InsufficentFundsError when insufficient"
>> ..
>
> Yes.  This style of specification has a lot of documentation value.  You
> look at the RDoc for a method that looks like what you want, and then
> you can look at the spec to get concrete examples of how it's used.
>
> A friend of mine has toyed with the idea of putting the specs directly
> in the RDoc, or generating RDoc from the specs.  Seems promising.

I want to hear more about this. It's something that I've been toying
with in my head, not so much in code.
David C. (Guest)
on 2008-12-16 22:59
(Received via mailing list)
On Tue, Dec 16, 2008 at 2:51 PM, Ben M. <removed_email_address@domain.invalid> 
wrote:
>>>> 2008, going over some of the rules I've collected for interpreting
>>> describe blocks named after methods.  I posted the comment below with my
>> well):
>
> 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
doco output:

Stack
  #pop
    returns the top element
    removes the top element
  #peek
    returns the top element
    does not remove the top element

etc.

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.
Ben M. (Guest)
on 2008-12-16 23:01
(Received via mailing list)
Lenny M. wrote:
>>
>
> level, it often makes perfect sense to describe the behavior of the
> it "should raise an InsufficentFundsError"
>
> examples. Or, you may find that you didn’t need that method at all.
> would only be distracting or messy at the current level. Using object
> other stuff or extra
> setup._______________________________________________
> rspec-users mailing list
> removed_email_address@domain.invalid
> http://rubyforge.org/mailman/listinfo/rspec-users

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 value.

-Ben
Lenny M. (Guest)
on 2008-12-19 19:27
(Received via mailing list)
On Dec 16, 2008, at 3:58 PM, Ben M. wrote:

>>>
>>
>> </quote>
>> here.
>>
>> behaviors and methods on an object. When you name an example after
>> difference between speccing behavior at the application level vs.
>> granularity.
>> removed_email_address@domain.invalid
>> http://rubyforge.org/mailman/listinfo/rspec-users
>
> 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.)

> Another reason why I think I like using method names in contexts is
> value.
>
> -Ben


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".

-lenny
Avdi G. (Guest)
on 2008-12-19 20:00
(Received via mailing list)
On Fri, Dec 19, 2008 at 12:02 PM, Lenny M. 
<removed_email_address@domain.invalid> wrote:
> 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".

I'd like to remind folks of something I pointed out at the top of the
article: the definition of a "code smell" is a pattern that *might*
indicate something is amiss. It's not a surety.

I agree that naming description blocks after methods is *less* of a
smell than naming examples after methods.  I've been known to name
contexts after methods, especially when spec-ing a) Rails helper
methods; and b) public library APIs.  I don't feel guilty for this.

Where a description block named for a method becomes a more probable
indicator of a design issue is when it's coupled with a block that
goes on and on for many examples.  This often indicates that the
method being described is doing too much, and wants to be either
broken up or factored out into another class.

I don't pretend to be a canonical source for RSpec best practices.
Lakshan asked me for an article on RSpec practices and I listed some
of the guidelines that have served me well.  He said some nice things
at the top of the article which I'm not sure were wholly warranted.
Your mileage, as always, may vary.

Anyway I'm happy to hear that some people got at least a little value
out of the article, and I appreciate all the feedback.

--
Avdi

Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com
Ben M. (Guest)
on 2008-12-19 20:17
(Received via mailing list)
Avdi G. wrote:
> indicate something is amiss. It's not a surety.
>

Of course, I always treat code smells as indicators and not dictators.
:)
>
> I don't pretend to be a canonical source for RSpec best practices.
> Lakshan asked me for an article on RSpec practices and I listed some
> of the guidelines that have served me well.  He said some nice things
> at the top of the article which I'm not sure were wholly warranted.
> Your mileage, as always, may vary.
>
> Anyway I'm happy to hear that some people got at least a little value
> out of the article, and I appreciate all the feedback.
>
>
I definitely got some value out of it!  In fact I have already started
adopting some of the patterns you shared, so thank you for writing
it.    My response to Lenny was in no means trying to discount the
article but rather just stating my view on that particular code smell.
I apologize if you felt like my reply was trying to discredit the
article.

-Ben
Lenny M. (Guest)
on 2008-12-19 22:44
(Received via mailing list)
On Dec 19, 2008, at 12:55 PM, Avdi G. wrote:

> article: the definition of a "code smell" is a pattern that *might*
> method being described is doing too much, and wants to be either
>
> --
> Avdi
>

Just to clarify...I thought most of your article was good stuff and I
can appreciate how difficult it is to articulate this kind of stuff.
I really just had a problem with that one smell as I understood it
from your article since it contradicted advice I often give about
coding outside in. I just wanted to get some reassurance that I
wasn't steering my fellow employees in the wrong direction. FWIW, I
agree with the way you state things above. Thanks for taking the time
to share.

-lenny
This topic is locked and can not be replied to.