[rspec-users] simple == with prettier error messages + good documentation

Matt Wynne matt at mattwynne.net
Thu Jan 29 19:07:16 EST 2009


On 29 Jan 2009, at 22:20, David Chelimsky wrote:

> On Thu, Jan 29, 2009 at 3:50 PM,  <r_j_h_box-sf at yahoo.com> wrote:
>>>>>>
>>>>>> On Thu, Jan 29, 2009 at 12:00 PM, <r_j_h_box-sf at yahoo.com> wrote:
>>>>>>>
>>>>>>> Hi all,
>>>>>>>
>>>>>>> I've found myself writing a thing I think is less than optimal,
>>>>>>> looking
>>>>>>> for suggestions.  The context is, I'm testing a result, and as  
>>>>>>> a part
>>>>>>> of
>>>>>>> that test, I might verify two or three things, which are  
>>>>>>> individually
>>>>>>> relevant but not really discrete results (?).
>>>>>>>
>>>>>>> Here's my thinking process, using a toy example:
>>>>>>>
>>>>>>> foo.should == bar (or foo.should_not be_nil)
>>>>>>>
>>>>>>>> expected not to be nil, but was
>>>>>>>
>>>>>>> (hm, not very informative)
>>>>>>>
>>>>>>> if( foo == nil )
>>>>>>>   "failure to setup foo".should == "foo should be set to the  
>>>>>>> thing
>>>>>>> that
>>>>>>> will be rendered"
>>>>>>> end
>>>>>>>
>>>>>>>> expected "foo should be set to the thing that will be  
>>>>>>>> rendered",
>>>>>>>> got "failure to setup foo" (using ==)
>>>>>>>
>>>>>>> I've used this, by example, for a test on a dependency  
>>>>>>> (imagemagick),
>>>>>>> where if the dependency isn't found, I show a decent message  
>>>>>>> with
>>>>>>> info
>>>>>>> the
>>>>>>> tester can use to resolve it.  And, as I mentioned, I've used  
>>>>>>> it for
>>>>>>> revealing more details in cases where the it "" + the generic  
>>>>>>> error
>>>>>>> aren't
>>>>>>> informative.
>>>>>>>
>>>>>>> I'm satisfied using this method for things like detecting a  
>>>>>>> failure
>>>>>>> to
>>>>>>> use
>>>>>>> a test-helper correctly - works fine, doesn't get in my way as  
>>>>>>> part
>>>>>>> of
>>>>>>> the
>>>>>>> documentation.  Which brings me to the problem I'm concerned  
>>>>>>> about:
>>>>>>>
>>>>>>> With this method, nothing come out in the generated spec-docs to
>>>>>>> represent
>>>>>>> the thing I'm conditionally requiring.
>>>>>>>
>>>>>>> I guess I could get more fine-grained with my it()'s, but I've  
>>>>>>> been
>>>>>>> preferring a more general statement for it(), that gives the  
>>>>>>> sense
>>>>>>> without
>>>>>>> the detail.

I really do suggest setting up the context in the before() block of a  
describe (example group), then using each 'it' (example) to hold an  
assertion. It's a tried and tested way of doing it for me, but it does  
take some getting used to when you move over from xUnit style tests.

>>>>>>>
>>>>>>>
>>>>>>> Any suggestions?
>>>>>>
>>>>>> I can't think of anything that wouldn't result in something that
>>>>>> requires
>>>>>> more writing as of now. Maybe we need a new construct like:
>>>>>> it "does something" do
>>>>>> with_message "this is a more specific message" do
>>>>>>   foo.should == bar
>>>>>> end
>>>>>> end
>>>>>> WDYT?
>>>>>>
>>>>>
>>>>> I think that would be useful. Maybe make it more explicit that  
>>>>> it's an
>>>>> error message:
>>>>>
>>>>> on_error "bla" do
>>>>> ...
>>>>> end
>>>>>
>>>>> on_failure "..." do ????
>>>>
>>>> I like "on_failure", as it's consistent with RSpec's output. Eg:
>>>> 31 examples, 0 failures
>>>>
>>>> What could be done to make the construct more sentence-like? If  
>>>> used in
>>>> this
>>>> manner:
>>>>
>>>> it 'should do something' do
>>>> on_failure "@foo is nil" do
>>>>   @foo.should_not be_nil
>>>> end
>>>> end
>>>>
>>>> It reads like this to me:
>>>> If "@foo is nil" fails, execute the block.
>>>>
>>>> These are a bit verbose, but what do you think these approaches?:
>>>> http://gist.github.com/54726
>>>
>>> I'll take that gist and raise you one:
>>>
>>> http://gist.github.com/54750 (Suggestion #3)
>>>
>>
>> Upped:
>>
>> http://gist.github.com/54758

I do find myself hitting this sometimes, especially when I use rspec  
assertions in Cucumber steps - I usually stick to one assertion per  
example in RSpec so it isn't a problem when I'm writing unit tests.

However we do have a couple of alternatives already, without extending  
RSpec any more:
(1) just use traditional test/unit assertions instead (works OK in  
Cucumber steps, though obviously they don't read quite so well)
(2) write a custom matcher

We could also pretty easily extend the existing matchers, just taking  
a failure message in the factory method, e.g:

http://gist.github.com/54849

I agree this discussion should move to a ticket. But it seems I am to  
lazy to do it myself ;)


Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com



More information about the rspec-users mailing list