RSpec vs. Test::Unit

0 views
Skip to first unread message

Francis Hwang

unread,
Oct 12, 2008, 8:16:06 PM10/12/08
to thought...@googlegroups.com
Hey, it occurred to me we've never discussed this before here, and if
some of you find this a tiresome topic forgive me, but: Do you have a
strong preference for RSpec over Test::Unit? And if so, why?

Francis Hwang
http://fhwang.net/

dbl...@wobblini.net

unread,
Oct 12, 2008, 9:02:49 PM10/12/08
to thought...@googlegroups.com
Hi --

On Sun, 12 Oct 2008, Francis Hwang wrote:

>
> Hey, it occurred to me we've never discussed this before here, and if
> some of you find this a tiresome topic forgive me, but: Do you have a
> strong preference for RSpec over Test::Unit? And if so, why?

I have a very strong preference for TestUnit. I'm in the category of
people who have the greatest respect for what RSpec has accomplished,
but who can't stand its syntax.

I can get a little more technical about it, though I hasten to add
that I'm not trying to sway anyone. This is just an account of my
perception of it.

The thing I dislike most is "should". When I look at this:

x(y).should == z

I see a statement which I assume will evaluate to either true or
false. What I don't see is any kind of tripwire or trigger that does
anything *with* that value. There's nothing to suggest that the value
matters. I'm left thinking, "OK, now we know that it *should* equal z.
Are there any plans to find out whether or not it does?"

Similarly, things like this:

x.should_receive(:a).and_return(:b)

don't communicate any kind of branching logic. I understand how it's
engineered, but I don't like the fit. I'm probably too conservative
about "magic dots". I like to be able to read from left to right and
have some sense of what's being returned from each method call, and
*why*. I understand that x.should_receive(:a) returns some object that
has an and_return method, and that knows whether or not x receives :a
(though, again, it's unclear *when* this hurdle is going to be
jumped). But I don't get a sense of why method-calling semantics (the
dot) are the best way to express what's happening.

I'd rather see something like:

x.register_spec do
upon_receiving(:a) { :b }
end

x.check_specs do
a # blow up if it isn't :b
end

I don't claim that that's very polished (and I actually don't like the
stealth instance_eval that's implied there :-) but it feels to me like
the various semantic features of Ruby are meshing better with the
semantics of the task at hand than when things are strung together
with dots.

I also don't like the whole thing about trying to make it sound like
English. I understand the concept of making it more intelligible to
non-programmers, but if you look at an extensive RSpec file, I doubt
you'll think that a non-programmer has the slightest chance of
understanding it. It's good that RSpec can generate reports of
requirements and so forth. Given that it can do that, I believe it
would be OK for it to give up on trying to make the code itself sound
like sentences.

In sum, I consider RSpec a tremendous accomplishment from many
perspectives, but it doesn't call out to me personally.


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

Austin Ziegler

unread,
Oct 12, 2008, 9:29:26 PM10/12/08
to thought...@googlegroups.com
I don't like rspec. I'm not sure why; it just doesn't look very good
to me.

I do think that "shoulda" looks interesting, but I've never used it.

-a

Sent from my iPhone, and only one contact in

James Britt

unread,
Oct 12, 2008, 9:31:24 PM10/12/08
to thought...@googlegroups.com
Francis Hwang wrote:
> Hey, it occurred to me we've never discussed this before here, and if
> some of you find this a tiresome topic forgive me, but: Do you have a
> strong preference for RSpec over Test::Unit? And if so, why?

At Happy Camper Studios, we've all agreed to use RSpec. I think I was
leaning that way anyways, but I'm not really thrilled with the idea that
the tests/specs "read like English", because they really don't.

A problem I've run into is that the resulting tests are not really
natural language, yet not straight-up Ruby, either. For example, I prefer

foo.should == bar

rather than

foo.should_be bar

I'm increasingly wanting to just write obvious Ruby code rather than use
some quasi-english DSL for things; less magic over all, and I don't have
to keep shifting mental parsers.

I also think that availability of "should_receive" lead folks to test
the implementation, not the behavior.

And mocks and stubs have (for me, and maybe I'm doing it wrong) a
tendency to leave residue, such that later use of classes that have been
mocked in entirely separate specs are not what they should be.

On the other hand, we've recently started using Cucumber for
integration/acceptance testing (it's the replacement for RSpec's story
runner) and it seems to work quite well for its purposes. We've hooked
it into JRuby/Swing apps with (so far) minor trouble.

I've also used Bacon (from chris2) a little bit; it may be less
magical than RSpec seems to me.

--
James Britt

www.happycamperstudios.com - Wicked Cool Coding
www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff

James Gray

unread,
Oct 12, 2008, 10:36:44 PM10/12/08
to thought...@googlegroups.com
On Oct 12, 2008, at 8:02 PM, dbl...@wobblini.net wrote:

> On Sun, 12 Oct 2008, Francis Hwang wrote:
>
>>
>> Hey, it occurred to me we've never discussed this before here, and if
>> some of you find this a tiresome topic forgive me, but: Do you have a
>> strong preference for RSpec over Test::Unit? And if so, why?
>
> I have a very strong preference for TestUnit. I'm in the category of
> people who have the greatest respect for what RSpec has accomplished,
> but who can't stand its syntax.

I think you are very wise. I agree 100%.

> I can get a little more technical about it, though I hasten to add
> that I'm not trying to sway anyone. This is just an account of my
> perception of it.
>
> The thing I dislike most is "should". When I look at this:
>
> x(y).should == z

The day RSpec died for me was the day I found myself needing to
explain syntax like the following to a student:

a.should be_empty

"OK, you know all that stuff I've been teaching you about methods…
how you can just tuck some logic away in there and then trigger it
anytime you need to rerun that code? Well, that's not how you test
them."

Ouch.

James Edward Gray II

Francis Hwang

unread,
Oct 13, 2008, 11:34:20 AM10/13/08
to thought...@googlegroups.com
On Oct 12, 2008, at 9:31 PM, James Britt wrote:

> And mocks and stubs have (for me, and maybe I'm doing it wrong) a
> tendency to leave residue, such that later use of classes that have
> been
> mocked in entirely separate specs are not what they should be.

Care to unpack this? What sort of "residue" do you mean?

Francis Hwang
http://fhwang.net/


Francis Hwang

unread,
Oct 13, 2008, 11:37:07 AM10/13/08
to thought...@googlegroups.com
On Oct 12, 2008, at 10:36 PM, James Gray wrote:
> The day RSpec died for me was the day I found myself needing to
> explain syntax like the following to a student:
>
> a.should be_empty
>
> "OK, you know all that stuff I've been teaching you about methods…
> how you can just tuck some logic away in there and then trigger it
> anytime you need to rerun that code? Well, that's not how you test
> them."
>
> Ouch.

Are you saying that

assert a.empty?

is preferable because it keeps people focused on the method :empty?

Sorry if I'm sounding obtuse, I'm just trying to unpack people's
feelings on the subject and I'm finding all sorts of subtle
distinctions. FWIW, I prefer RSpec, but not so much because of the
should stuff, and more because of the ability to use nested blocks
instead of classes & methods to delineate tests and contexts. It's a
small difference but it does seem to make my test code a lot easier to
read.

Francis Hwang
http://fhwang.net/

Gregory Brown

unread,
Oct 13, 2008, 11:40:53 AM10/13/08
to thought...@googlegroups.com
On Mon, Oct 13, 2008 at 11:37 AM, Francis Hwang <se...@fhwang.net> wrote:

> Sorry if I'm sounding obtuse, I'm just trying to unpack people's
> feelings on the subject and I'm finding all sorts of subtle
> distinctions. FWIW, I prefer RSpec, but not so much because of the
> should stuff, and more because of the ability to use nested blocks
> instead of classes & methods to delineate tests and contexts. It's a
> small difference but it does seem to make my test code a lot easier to
> read.

It sounds like you're looking for Shoulda.

-greg

--
Technical Blaag at: http://blog.majesticseacreature.com | Non-tech
stuff at: http://metametta.blogspot.com

Jeremy McAnally

unread,
Oct 13, 2008, 11:41:11 AM10/13/08
to thought...@googlegroups.com
I see this argument a lot (and I agree with it). That's why I wrote
Context (http://www.github.com/jeremymcanally/context/). As soon as I
figure out why `rake test` hates it, then it's what I'll use for
everything.

I also see people make the argument that the matchers are a really
nice syntax, you really need the matchers, they keep you focused on
behavior, etc. So that's why I wrote matchy
(http://www.github.com/jeremymcanally/matchy).

All said, even though the two libs together give you almost complete
API compat with RSpec, people I've shown it to said they won't be
switching. Generally I think people just like what they like, and
once they get used to it, won't switch to something else. Which is
sort of unfortunate, because I think the Test::Unit syntax isn't
perfect and RSpec (even though I use it every day at work) isn't the
best solution to this whole testing thing.

And it seems like miniunit is going to make the syntax situation even worse.

--Jeremy
--
http://jeremymcanally.com/
http://entp.com/
http://omgbloglol.com

My books:
http://manning.com/mcanally/
http://humblelittlerubybook.com/ (FREE!)

dbl...@wobblini.net

unread,
Oct 13, 2008, 11:48:09 AM10/13/08
to thought...@googlegroups.com
Hi --

On Mon, 13 Oct 2008, Francis Hwang wrote:

>
> On Oct 12, 2008, at 10:36 PM, James Gray wrote:
>> The day RSpec died for me was the day I found myself needing to
>> explain syntax like the following to a student:
>>
>> a.should be_empty
>>
>> "OK, you know all that stuff I've been teaching you about methods…
>> how you can just tuck some logic away in there and then trigger it
>> anytime you need to rerun that code? Well, that's not how you test
>> them."
>>
>> Ouch.
>
> Are you saying that
>
> assert a.empty?
>
> is preferable because it keeps people focused on the method :empty?

I think it's better because it both exercises and documents the object
interface more precisely. I also really dislike things like be_empty.
That's the pseudo-English thing at its worst. I can never remember
whether it's:

should_be empty
should_be(:empty)

etc. There's a real impedance mismatch between Ruby and English at
that point.

James Gray

unread,
Oct 13, 2008, 12:43:47 PM10/13/08
to thought...@googlegroups.com
On Oct 13, 2008, at 10:37 AM, Francis Hwang wrote:

> On Oct 12, 2008, at 10:36 PM, James Gray wrote:
>> The day RSpec died for me was the day I found myself needing to
>> explain syntax like the following to a student:
>>
>> a.should be_empty
>>
>> "OK, you know all that stuff I've been teaching you about methods…
>> how you can just tuck some logic away in there and then trigger it
>> anytime you need to rerun that code? Well, that's not how you test
>> them."
>>
>> Ouch.
>
> Are you saying that
>
> assert a.empty?
>
> is preferable because it keeps people focused on the method :empty?

Yeah, I was really disappointed at how lost in the magic our
discussion of methods got. Why would we tell students to just call
that method anytime they need to rerun that code and then not do that
to test the results.

> Sorry if I'm sounding obtuse, I'm just trying to unpack people's
> feelings on the subject and I'm finding all sorts of subtle
> distinctions.

Sure. I should have been more clear.

> FWIW, I prefer RSpec, but not so much because of the
> should stuff, and more because of the ability to use nested blocks
> instead of classes & methods to delineate tests and contexts. It's a
> small difference but it does seem to make my test code a lot easier to
> read.

Yeah, nested blocks and test descriptions in strings are something
RSpec got very right. I feel it got the "assertions" very wrong
though. Definitely have a look at shoulda and test/spec. RSpec is
not the only way to get the good stuff.

James Edward Gray II

dbl...@wobblini.net

unread,
Oct 13, 2008, 1:40:02 PM10/13/08
to thought...@googlegroups.com
I just wanted to second the recommendation to look at "shoulda". In
spite of my dislike of the "should" idiom, I like shoulda, because it
lets you use the best of both.


David

James Britt

unread,
Oct 13, 2008, 3:45:12 PM10/13/08
to thought...@googlegroups.com


In one spec I mock class Foo so that target code that needs to call
(say) Foo.bar is happy.

Then, in a separate spec, one that needs to use the real Foo class, I
get errors that Foo doesn't have one or another method, and find that
the code is using the mock object, not the actual object. So there
seems to be poor isolation among specs.

Basically, once a spec is ended I would want all the mocks and stubs to
vanish. But they linger. There's every chance I'm doing something
wrong; good docs and examples for RSpec are hard for me to find.

(The upside is that it makes me mock-adverse; I've come to think of
mocks as a code smell. But, sometimes it's the better way to get a spec
moving, especially if I'm adding specs after the fact.)

Reply all
Reply to author
Forward
0 new messages