Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

RSpec is not the reason your rails test suite is slow

View output.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
[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
View output.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
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

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.

@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. :-)

@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. :)

@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.

@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. :)

@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!" :-)

@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. :)

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.

'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?

@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.

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

+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
Something went wrong with that request. Please try again.