Francis Hwang
http://fhwang.net/
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!
I do think that "shoulda" looks interesting, but I've never used it.
-a
Sent from my iPhone, and only one contact in
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
> 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
> 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/
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/
> 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
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.
> 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
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.)