RSpec vs Screw.Unit


#1

Hi

Hope this isn’t OT. I’m currently contemplating using the Dojo[1]
JavaScript framework, and I suspect it’s powerful enough that using
Cucumber features and Celerity alone will quickly leave me wanting
lower-level unit specs for the JS.

So I just wondered if anyone here has used Screw.Unit[2], and if so,
how does it compare to RSpec? It seems to offer many of the features
of RSpec (with the notable exception of shared behaviours).

Thanks
Ashley

[1] http://dojotoolkit.org/
[2] http://github.com/nkallen/screw-unit/tree/master


http://www.patchspace.co.uk/


#2

On Thu, Oct 16, 2008 at 10:28 PM, Ashley M.
removed_email_address@domain.invalid wrote:

I haven’t used it, but I have heard good things about JSSpec and Jack
javascript mocking.

Aslak


#3

On Oct 16, 2008, at 4:28 PM, Ashley M. wrote:

Hi

Hope this isn’t OT. I’m currently contemplating using the Dojo[1]
JavaScript framework, and I suspect it’s powerful enough that using
Cucumber features and Celerity alone will quickly leave me wanting
lower-level unit specs for the JS.

So I just wondered if anyone here has used Screw.Unit[2], and if so,
how does it compare to RSpec? It seems to offer many of the
features of RSpec (with the notable exception of shared behaviours).

I’ve been using it a bunch, and I must say that so far I’ve really
enjoyed it. Here are the downsides that I’ve noticed:

  1. It’s much more verbose, and doesn’t read quite as cleanly as
    rspec. Instead of foo.should == “bar”, you’ll end up with:

expect(foo()).to(equal, bar());

Which just gets a bit syntax heavy. I’m sure that they didn’t want to
polute the global namespace, but maybe a function like this might
solve the problem:

Object.prototype.should = function(obj) {
expect(this).to(equal, arg);
};

  1. The matchers just aren’t there the way they are for rspec. This
    can make a big difference to code readability. Obviously, you could
    build them yourself. (This is just a matter of time, and standing on
    the shoulders of giants sort of thing).

  2. I haven’t looked very hard, but I haven’t found a plain text
    runner yet. Obviously it’s going to need a browser if you’re planning
    on doing DOM interaction (which is very easy). For me, though, a
    plain text runner would be awsome.

Scott


#4

On Thu, Oct 16, 2008 at 4:28 PM, Ashley M.
removed_email_address@domain.invalid wrote:

So I just wondered if anyone here has used Screw.Unit[2], and if so, how
does it compare to RSpec? It seems to offer many of the features of RSpec
(with the notable exception of shared behaviours).

I just want to thank you for reminding to checkout Screw.Unit.
Somebody mentioned it the other day but I forgot to look it up. We’ve
been using JSSpec for our JS tests, but it looks like Screw is JSSpec
on crack. It addresses the main thing I missed form RSpec: nested
describes. I’m definitely going to be trying this on my next project.


Avdi

Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com


#5

On Oct 17, 2008, at 10:41 am, Matt W. wrote:

I’m also interested in this, as we’re currently deciding which route
to go.

I like the philosophy behind screw unit - it feels like the team
want to give us RSpec for javascript.

That’s the feeling I got, that SU is trying to be a cleaner, slicker
implementation of JSSpec. I saw someone try JSSpec a few months back
and very quickly hit issues with message expectations. As for whether
it’s “JSSpec on crack*” I will have to try it to see…

One of the things that has irritated me (and generally does with
javascript unit testing) is that running the tests is quite slow and
requires selenium. I did a little spike to run them via celerity
instead:
http://gist.github.com/15273

Awesome! I’ll have to try that when I get into JS.

Thanks
Ashley

  • Or Akuz if you’re in the UK


http://www.patchspace.co.uk/


#6

On of the things I’ve noticed with ScrewUnit is to quote the ScrewUnit
wiki:

“The dynamic nature of JavaScript makes mocking frameworks mostly
unnecessary”

A small but interesting difference from using Ruby, Rspec and its
built-in mocking framework.


Joseph W.
http://www.joesniff.co.uk


#7

On Fri, Oct 17, 2008 at 10:54 AM, Joseph W.
removed_email_address@domain.invalid wrote:

“The dynamic nature of JavaScript makes mocking frameworks mostly
unnecessary”

A small but interesting difference from using Ruby, Rspec and its built-in
mocking framework.

So… Wait. Is the implication here that Ruby is too static? Or
just the way people are using Ruby, including RSpec?

I guess I’ll have to check that other framework out to see what that
means. It’s not very often that you hear anyone suggesting that Ruby
isn’t dynamic enough.


Have Fun,
Steve E. (removed_email_address@domain.invalid)
ESCAPE POD - The Science Fiction Podcast Magazine
http://www.escapepod.org


#8

On 17 Oct 2008, at 06:44, Scott T. wrote:

so, how does it compare to RSpec? It seems to offer many of the
features of RSpec (with the notable exception of shared behaviours).

I’m also interested in this, as we’re currently deciding which route
to go.

I like the philosophy behind screw unit - it feels like the team want
to give us RSpec for javascript. One of the things that has irritated
me (and generally does with javascript unit testing) is that running
the tests is quite slow and requires selenium. I did a little spike to
run them via celerity instead:
http://gist.github.com/15273

  1. I haven’t looked very hard, but I haven’t found a plain text
    runner yet. Obviously it’s going to need a browser if you’re
    planning on doing DOM interaction (which is very easy). For me,
    though, a plain text runner would be awsome.

Do you mean a story-runner that just works on the javascript / HTML,
as opposed to running the full stack including the server-side?


#9

On Oct 17, 2008, at 11:42 AM, Stephen E. wrote:

So… Wait. Is the implication here that Ruby is too static? Or
just the way people are using Ruby, including RSpec?

Depends on what you want to do. Honestly, I find it much easier to
manipulate methods in javascript rather then ruby.

Here’s the essential complexity of a stub framework:

  1. Store the original method definition (if there is one).
  2. Replace the method definition with a new method, this time
    returning nil/undefined, or a set value.

after(:each) =>

  1. Restore the original method definition
  2. Cleanup any mess you’ve made

In Ruby, the first two steps ends up more or less like this:

(class << my_obj; self; end).instance_eval <<-HERE
alias_method :my_#{original_method}, #{my_method}
def #{my_method}
#{my_return_value}
end
HERE

In Javascript, it might look more or less like this:

var old_method = obj[my_method];
my_obj[my_method] = my_return_value;

The point is not that ruby is more static, but that it’s just a lot
more typing and metaprogramming hoops that you’ll need to jump
through. Also - notice that javascript, a prototype based language,
you can deal with the metaclass/singleton class seamlessly (since
there is no class). In Ruby you’ll want to be safe and not redefine
the method for the whole class (i.e., all instances of the class), but
only for the particular object you’re stubbing.

As for the mocking part, this too seems to be an issue of language. I
suppose it would depend on how sophisticated you want to get. Here’s
what appears to be essential for a mock:

  1. the ability to stub methods on it
  2. An “empty” object - one with no predefined methods.
  3. complaining when a method is called on it which hasn’t explicitly
    been defined.

#2 seems to be a shoe-in for Javascript - since a regular old object
is an “empty” object. In Ruby, you’ll need something more or less
like BlankSlate, which undef’s all it’s methods. As for #3, I’m
pretty sure that Ruby’s method_missing allows one to raise an
exception easily. Not sure what a Javascript mocking framework would
do in this case.

Scott


#10

Scott T. removed_email_address@domain.invalid writes:

As for #3, I’m
pretty sure that Ruby’s method_missing allows one to raise an
exception easily. Not sure what a Javascript mocking framework would
do in this case.

I’m not sure that I buy that this feature is very important. Both
Javascript and Ruby blow up when you call a method that doesn’t exist on
it anyway. What’s the difference between “Received unexpected message
‘foo’” and “NoMethodError ‘foo’”?

Pat


#11

On Sat, Oct 18, 2008 at 12:53 AM, Scott T.
removed_email_address@domain.invalid wrote:

In Javascript, it might look more or less like this:

var old_method = obj[my_method];
my_obj[my_method] = my_return_value;

That’s an interesting syntax comparison, thanks, but not really what I
was reacting to. The statement of import (with emphasis added) was
"“The dynamic nature of JavaScript makes mocking frameworks MOSTLY
UNNECESSARY.”

This doesn’t imply a simpler mocking framework, as you describe. It
implies a fundamental mindshift in how testing gets done.

I should probably stop speculating about it here and just do some
reading about it. (Or some coding, but I’ve already invented two
“distract myself” projects this week and don’t need a third in a new
language.)


Have Fun,
Steve E. (removed_email_address@domain.invalid)
ESCAPE POD - The Science Fiction Podcast Magazine
http://www.escapepod.org


#12

On Oct 18, 2008, at 9:19 AM, Pat M. wrote:

it anyway. What’s the difference between “Received unexpected message
‘foo’” and “NoMethodError ‘foo’”?

Unless I’m mistaken, it’s only when another method gets called on a
missing method that an error gets raised:

o = {};
Object

o.foo
o.foo === undefined
true

o.foo.bar
TypeError: o.foo is undefined

Also, I found this last night:

http://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Global_Objects:Object:_noSuchMethod
.

BTW, Pat - Have you still been working on integrating test spy into
rspec?

Scott


#13

On Oct 18, 2008, at 10:30 AM, Stephen E. wrote:

"“The dynamic nature of JavaScript makes mocking frameworks MOSTLY
UNNECESSARY.”

This doesn’t imply a simpler mocking framework, as you describe. It
implies a fundamental mindshift in how testing gets done.

AH - that’s interesting. I didn’t take it as any sort of mindshift in
testing. I thought that README/blogpost was simply saying that a mock
framework is unnecessary because the syntax is so easy. But only
mostly unnecessary, because either 1) there will be times where
you’ll need to tear things down, AND/OR 2) You could build a tiny stub/
mock framework around this stuff very easily for small syntactical
gains.

Interesting idea, though, and maybe it does cause a mindshift in
testing.

Scott


#14

On Oct 19, 2008, at 12:14 PM, Pat M. wrote:

do in this case.

o = {};
Object

o.foo

You would need to do o.foo() to actually call the method. That will
give you “o.foo is undefined”

Oops. I feel like a tool. Guess ruby syntax still invades my brain.

BTW, Pat - Have you still been working on integrating test spy into
rspec?

Nope, I found not_a_mock [1] and it works well.

Any plans to roll not_a_mock into rspec core?

Scott


#15

Scott T. removed_email_address@domain.invalid writes:

Javascript and Ruby blow up when you call a method that doesn’t
exist on
it anyway. What’s the difference between “Received unexpected message
‘foo’” and “NoMethodError ‘foo’”?

Unless I’m mistaken, it’s only when another method gets called on a
missing method that an error gets raised:

o = {};
Object

o.foo

You would need to do o.foo() to actually call the method. That will
give you “o.foo is undefined”

BTW, Pat - Have you still been working on integrating test spy into
rspec?

Nope, I found not_a_mock [1] and it works well.

Pat

[1] http://notahat.com/not_a_mock


#16

On Sun, Oct 19, 2008 at 9:44 PM, Scott T.
removed_email_address@domain.invalid wrote:

pretty sure that Ruby’s method_missing allows one to raise an
missing method that an error gets raised:

Oops. I feel like a tool. Guess ruby syntax still invades my brain.

BTW, Pat - Have you still been working on integrating test spy into
rspec?

Nope, I found not_a_mock [1] and it works well.

Any plans to roll not_a_mock into rspec core?

No, but if you’d like to submit a patch w/ a wrapper we can add it to
the list of supported frameworks.


#17

On Oct 19, 2008, at 12:14 PM, Pat M. wrote:

BTW, Pat - Have you still been working on integrating test spy into
rspec?

Nope, I found not_a_mock [1] and it works well.

Also, relevant to the Screw.Unit and the spying threads, I’ve hacked
together a Javascript mocking/stubbing framework which uses the test-
spy pattern, if anyone is interested:

http://github.com/smtlaissezfaire/espionage/tree/master

Scott


#18

On Oct 22, 2008, at 9:46 AM, David C. wrote:

message

o.foo

Nope, I found not_a_mock [1] and it works well.

Any plans to roll not_a_mock into rspec core?

No, but if you’d like to submit a patch w/ a wrapper we can add it to
the list of supported frameworks.

Yeah, I’ll do this eventually if no one else does it, although I’ll
probably want to add support for LH #576 first:

http://rspec.lighthouseapp.com/projects/5645/tickets/576-switch-mock-frameworks-at-run-time#ticket-576-1

Scott