Skip to content

Instantly share code, notes, and snippets.

@dchelimsky
Created March 16, 2012 15:28
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dchelimsky/2050539 to your computer and use it in GitHub Desktop.
Save dchelimsky/2050539 to your computer and use it in GitHub Desktop.
RSpec is not the reason your rails test suite is slow
[david: compare]$ # at this point we have a stock rails app with no minitest tests and one pending rspec example
[david: compare]$
[david: compare]$ time rake test
Run options:
# Running tests:
Finished tests in 0.030419s, 0.0000 tests/s, 0.0000 assertions/s.
0 tests, 0 assertions, 0 failures, 0 errors, 0 skips
real 0m5.694s
user 0m4.503s
sys 0m0.811s
[david: compare]$ time rake spec
/Users/david/.rvm/rubies/ruby-1.9.3-p0/bin/ruby -S rspec ./spec/models/thing_spec.rb
*
Pending:
Thing add some examples to (or delete) /Users/david/tmp/compare/spec/models/thing_spec.rb
# No reason given
# ./spec/models/thing_spec.rb:4
Finished in 0.00072 seconds
1 example, 0 failures, 1 pending
real 0m4.918s
user 0m3.839s
sys 0m0.697s
[david: compare]$
[david: compare]$ echo 'require "test_helper"
>
> class ThingTest < ActiveSupport::TestCase
> test "empty" do
> end
> end
> ' > test/unit/thing_test.rb
[david: compare]$
[david: compare]$ echo 'require "spec_helper"
>
> describe Thing do
> example "empty" do
> end
> end
> ' > spec/models/thing_spec.rb
[david: compare]$
[david: compare]$ time rake test
Run options:
# Running tests:
.
Finished tests in 0.078296s, 12.7720 tests/s, 0.0000 assertions/s.
1 tests, 0 assertions, 0 failures, 0 errors, 0 skips
real 0m5.802s
user 0m4.565s
sys 0m0.847s
[david: compare]$ time rake spec
/Users/david/.rvm/rubies/ruby-1.9.3-p0/bin/ruby -S rspec ./spec/models/thing_spec.rb
.
Finished in 0.00475 seconds
1 example, 0 failures
real 0m4.950s
user 0m3.903s
sys 0m0.725s
[david: compare]$
[david: compare]$ echo 'require "test_helper"
>
> class ThingTest < ActiveSupport::TestCase
> 1000.times.map do |n|
> test "empty #{n}" do
> end
> end
> end
> ' > test/unit/thing_test.rb
[david: compare]$
[david: compare]$ echo 'require "spec_helper"
>
> describe Thing do
> 1000.times.map do |n|
> example "empty #{n}" do
> end
> end
> end
> ' > spec/models/thing_spec.rb
[david: compare]$
[david: compare]$ time rake test
Run options:
# Running tests:
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Finished tests in 0.753860s, 1326.5062 tests/s, 0.0000 assertions/s.
1000 tests, 0 assertions, 0 failures, 0 errors, 0 skips
real 0m6.730s
user 0m5.047s
sys 0m0.887s
[david: compare]$ time rake spec
/Users/david/.rvm/rubies/ruby-1.9.3-p0/bin/ruby -S rspec ./spec/models/thing_spec.rb
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Finished in 0.99978 seconds
1000 examples, 0 failures
real 0m6.023s
user 0m4.615s
sys 0m0.790s
rails new compare
cd compare
rails g model thing name:string
echo "gem 'rspec-rails', '2.9.0.rc2', :group => [:development, :test]" >> Gemfile
bundle
rails g rspec:install
rails g model thing name:string --skip-migration
rake db:migrate
rake db:test:prepare
# at this point we have a stock rails app with no minitest tests and one pending rspec example
time rake test
time rake spec
echo 'require "test_helper"
class ThingTest < ActiveSupport::TestCase
test "empty" do
end
end
' > test/unit/thing_test.rb
echo 'require "spec_helper"
describe Thing do
example "empty" do
end
end
' > spec/models/thing_spec.rb
time rake test
time rake spec
echo 'require "test_helper"
class ThingTest < ActiveSupport::TestCase
1000.times.map do |n|
test "empty #{n}" do
end
end
end
' > test/unit/thing_test.rb
echo 'require "spec_helper"
describe Thing do
1000.times.map do |n|
example "empty #{n}" do
end
end
end
' > spec/models/thing_spec.rb
time rake test
time rake spec
@coreyhaines
Copy link

Of course RSpec isn't the speed problem. Enough of us know that the speed problems come from loading unnecessary dependencies for the majority of your code, such as rails. Once people start designing their systems with this in mind, this becomes very clear.

@jgaskins
Copy link

@coreyhaines There are some skeptics that believe that RSpec is bloated and adds nothing valuable to a test suite. Apparently, these people think that unless something is difficult, it can't be efficient. :-)

@coreyhaines
Copy link

@jgaskins
I have talked to people with that opinion. They are free to have their opinions. In the end, though, there are many options people can choose. That's a beautiful thing. :)

@jgaskins
Copy link

@coreyhaines I agree it's definitely is nice to have the choice, but I wouldn't call believing RSpec to be a testing bottleneck to be an opinion — rather, I see it as FUD, usually caused by not knowing what's going on when they run bundle exec and/or require spec_helper.rb in their specs.

@coreyhaines
Copy link

@jgaskins
I try to stay away from getting into their reasons and saying they don't understand things. Whether it is true, or not, it just ends up leading to purse fights. :)
For the record, I neither use bundle exec to run my specs nor require spec_helper in most of my specs. :)

@jgaskins
Copy link

@coreyhaines lol You're very right. Unfortunately, my desire not to start flame wars on the internet is all too often at odds with my tendency to "someone is wrong on the internet!" :-)

@coreyhaines
Copy link

@jgaskins :) Yeah, staying out of it is a lot easier said than done. I contribute my fair share of purse fighting when people are wrong on the internet. :)

@matschaffer
Copy link

I'll bite :)

I don't think rspec itself is slow, but I do get the impression that rspec lends itself to writing slow tests via overly isolated assertions with before blocks. Granted, there are advantages to isolated assertions, deep nesting can lead to longer-than-necessary test setup. SCSS often suffers the same fate.

@gavingmiller
Copy link

'speed problems come from loading unnecessary dependencies for the majority of your code, such as rails'

@coreyhaines or anyone else, any links/advice on how to reduce those rails dependencies?

@matschaffer
Copy link

matschaffer commented Mar 22, 2012 via email

@EmmanuelOga
Copy link

@gavingmiller http://objectsonrails.com/ shows an approach of developing a rails app with tests that load only what's strictly necessary to run the tests. I haven't tried this approach yet but sounds interesting.

@coreyhaines
Copy link

coreyhaines commented Mar 22, 2012 via email

@eclubb
Copy link

eclubb commented Mar 24, 2012

Gary Bernhardt does a great job of showing how to reduce test dependencies at https://www.destroyallsoftware.com

@dreoliv
Copy link

dreoliv commented Mar 25, 2012

+1 to both DAS and Objects On Rails. Those were my sources of techniques to speed up my test suite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment