[rspec-users] How do I improve the readability of my specs

David Chelimsky dchelimsky at gmail.com
Thu May 27 10:01:11 EDT 2010


On May 27, 2010, at 8:39 AM, Nadal wrote:

> Thanks David for great explanation.
> 
> Just to be clear to David and others. As some of you might have
> noticed I have been asking a lot of questions starting last week. And
> that is because I never used rspec before. And now that I am reading
> the book and am trying to convert some of my tests from plain ruby
> style tests to rspec I am trying to engage in a conversation.
> 
> No offense to anyone.

No offense taken, and I apologize that my response appeared to direct negative energy your way. You just touched on a topic that I feel strongly about. DRY is widely misunderstood and oft misappropriated at the expense of other valuable principles that should be considered as well.

> Infact I salute David and other team members.
> It's just that I am being more vocal and bringing a perspective to the
> community. And ,I believe, if I have a question then others might have
> similar question and they might not take time to write in the forum.

Absolutely!

> Either way I am learning a lot and I hope community benefits. The book
> is great. And conversations like this one with real example makes for
> great supplement.

Absolutely, again! Bring on the questions.

Cheers,
David

> On May 27, 2:44 am, Matt Wynne <m... at mattwynne.net> wrote:
>> On 27 May 2010, at 04:44, David Chelimsky wrote:
>> 
>> 
>> 
>> 
>> 
>>> On May 26, 2010, at 9:37 PM, Nadal wrote:
>> 
>>>> Here is my spec.
>> 
>>>> describe Exception2db do
>>>> context "attributes" do
>>>>   subject { Exception2db.create(:exception => $exception_data_xml) }
>> 
>>>>   specify { subject.controller.should == 'exception2db/main' }
>>>>   specify { subject.error_message.should == 'RuntimeError: 46' }
>>>>   specify { subject.user_agent.should == "Mozilla/5.0 (Macintosh; U;
>>>> Intel Mac OS X 10_6_3; en-US) AppleWebKit/533.4 (KHTML, like Gecko)
>>>> Chrome/5.0.375.38 Safari/533.4" }
>>>> end
>>>> end
>> 
>>>> Here is specdoc.
>> 
>>>> Exception2db attributes
>>>> - should == "exception2db/main"
>>>> - should == "RuntimeError: 46"
>>>> - should == "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-US)
>>>> AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.38 Safari/533.4"
>> 
>>>> All the tests are passing. However the specdoc message is not very
>>>> clean.
>> 
>>>> How can I improve the message? What am I missing? The idea of wrapping
>>>> each of my specify inside "it" to just to have better message is not
>>>> very DRY.
>> 
>>> I look at it the other way: accepting unclear messages just to keep things DRY is missing the point.
>> 
>>> DRY is about reducing duplication of concepts, not letters. At its heart, DRY is about maintenance. Duplication can come in very sinister forms, like two methods with different names on two different objects that accomplish the same task. That's the sort of duplication that kills maintenance because a new requirement comes in and you don't even realize you have two places to change in the code base.
>> 
>>> Consider the following two examples:
>> 
>>> it "concats the first and last name" do
>>>  first_name = "David"
>>>  last_name = "Chelimsky"
>>>  person = Person.new(
>>>    :first_name => first_name,
>>>    :last_name => last_name
>>>  )
>>>  person.full_name.should == "#{first_name} #{last_name}"
>>> end
>> 
>>> it "concats the first and last name" do
>>>  person = Person.new(
>>>    :first_name => "David",
>>>    :last_name => "Chelimsky"
>>>  )
>>>  person.full_name.should == "David Chelimsky"
>>> end
>> 
>>> Which one is DRYer? You could argue the first one is, because the string literals are not repeated. You could argue that the second one is, because the variable names are not repeated. You might argue the first one is because, even though the variable names are repeated, the failure message you get if you type "frist_name" will be very informative. You might argue that typing "Chelmisky" in the second one would also give you an informative message. Also, the first one very likely duplicates the actual implementation of the full_name method. And on, and on, and on, and on.
>> 
>>> Here's what I don't really think you can argue against: the second one is easier to read and understand.
>> 
>>> In the example you gave, I have absolutely no idea what those specs are telling me about the Exception2db object. After some study, I _think_ I understand, but it took a minute. What I'd like to see in the specdoc output is something like:
>> 
>>> Exception2db
>>>  stores the controller
>>>  stores the runtime error
>>>  stores the user agent
>> 
>>> Now I know what this thing DOES. Sure, the spec is going to have more lines in it, but the concepts expressed in the specdoc are _different_ from the concepts in the expectations. In my book, that's not a DRY violation at all.
>> 
>>> HTH,
>>> David
>> 
>>> ps - there is some irony in the fact that I keep repeating myself on this exact topic on this list. I think I need to write this up in a blog post and point people to that in the future. Now THAT would be DRY.
>> 
>> Great explanation David.
>> 
>> There's a slightly different point about this, which is that in the BDD world we aspire to build things from the "outside in".
>> 
>> These splendid methods that automatically generate specdoc from code are great in simple cases, but very often it's advisable to start by writing a plain-english description of what you're setting out to do before you write any code. Jumping straight in to writing the code (the solution) without clearly having stated the goal can mean you miss a chance to get insights into your design.
>> 
>> cheers,
>> Matthttp://blog.mattwynne.net
>> _______________________________________________
>> rspec-users mailing list
>> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list