[rspec-users] Failure Messages in RSpec

Pat Maddox pergesu at gmail.com
Tue Sep 4 17:23:05 EDT 2007


On 9/4/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> On 9/4/07, Geoffrey Wiseman <geoffrey.wiseman at gmail.com> wrote:
> > > I come from the same background as you, so I hear where you're coming
> > > from. We made a conscious decision, however, not to support custom
> > > messages almost two years ago and I'm not sure if its ever even come
> > > up before. If it has, it was a long time ago.
> >
> > [nod]  Perhaps as I get into the mindset, I'll find this desire slips away.
> >
> > > If you follow the conventions of one expectation per example, and your
> > > example is well named, this is less of a problem. Here's a common
> > > idiom:
> > >
> > > describe Person do
> > >   def valid_attributes
> > >     {:name => 'joe smith'}
> > >   end
> > >   before(:each) do
> > >     @person = Person.new(valid_attributes)
> > >   end
> > >   it "should be valid with valid attributes" do
> > >     @person.should be_valid
> > >   end
> > >   it "should be invalid with no name" do
> > >     @person.name = nil
> > >     @person.should_not be_valid
> > >   end
> > > end
> >
> > Using this as an example, if a new validation rule is added, this test will
> > fail without indicating /why/.  Sure, I can get that answer in other ways,
> > but I'd hate to discover things like:
> >
> >  it "should be valid with valid attributes" do
> >   # puts @person.errors if !@person.valid
> >   @person.should be_valid
> > end
> >
> > (Which I've seen when people have to repeatedly diagnose issues in a test;
> > I'd prefer a failure message to the above)
> >
> > > Together, these different examples help to tell the whole story, and
> > > when one example fails you know why it's failing - its just that the
> > > message is in the example's name instead of a custom assertion
> > > message.
> >
> > > Make sense?
> >
> > Yes and no; test isolation and good names is a decent practice even in
> > XUnit, but clearly it's that much stronger in RSpec, and I'm in favour of
> > that.  However, I find that often test failures involve unexpected changes (
> > e.g. the REST service didn't return a status code of 201, as you expected,
> > because a validation rule changed and the validation failed), which aren't
> > as easy to message.
> >
> > Still, i'm willing to give this approach a shot and see if this bothers me
> > increasingly less.
>
> Personally, I'm open to the idea of custom messages - I just have no
> idea how that work syntactically. If you get to the point where you
> really feel the need for that feature (or before that point) please
> feel free to make suggestions about that.

What do you think about using a custom expectation matcher here?
be_valid can be its own matcher instead of using the predicate
matcher.  That way we can include extra info without polluting the
syntax, because as you said, this doesn't come up.

Of course that gets in the way of other objects that respond to
valid?, so I guess you could do a little bit of type-checking (if it's
an AR object then display errors, otherwise delegate to predicate
matcher) or create a separate matcher altogether.

What about something like:

it "should validate with valid attributes" do
  @person.should validate
end

'Person should validate with valid attributes' FAILED
expected object to validate, failed with errors:
Age can't be blank

Basically I think a custom expectation matcher works fine here, I just
don't know the best way to implement it.

Pat


More information about the rspec-users mailing list