6

My rspec tests seem to run extremely slow even with guard & spork.

Finished in 5.36 seconds
13 examples, 2 failures

I understand that there are several things I can do to optimize my tests & reduce interaction with the database, but I strongly suspect that the spec_helper has been improperly setup. I'm on rails 3.2.11 with mongoid. Database cleaner cleans up after every run.

spec_helper.rb

require 'rubygems'
require 'spork'
Spork.prefork do
  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  require 'rspec/autorun'
  require 'capybara/rspec'

  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
  DatabaseCleaner[:mongoid].strategy = :truncation

  RSpec.configure do |config|
    config.infer_base_class_for_anonymous_controllers = false
    config.order = "random"
    config.filter_run focus: true
    config.filter_run_excluding :remove => true
    config.run_all_when_everything_filtered = true
    config.include Mongoid::Matchers
    config.include Capybara::DSL
    ActiveSupport::Dependencies.clear
  end
end


Spork.each_run do
  Fabrication.clear_definitions
  RSpec.configure do |config|
    config.before(:each) do
      DatabaseCleaner.clean
    end
  end
end

UPDATE: The problem was with one of my tests. It was taking 3 seconds. Please check @Sam Peacey's answer for the command I used to get the below result

Dynamic Model should destroy collection when related source is destroyed
    2.46 seconds ./spec/models/dynamic_model_spec.rb:10
Dynamic Model Validations should validate uniqueness
    0.66357 seconds ./spec/models/dynamic_model_spec.rb:69
Ramandeep Singh
  • 5,063
  • 3
  • 28
  • 34
Rahul
  • 412
  • 4
  • 13
  • 5 seconds isn't that bad. Ruby isn't C you know... – beatgammit Mar 18 '13 at 07:37
  • 1
    For 13 tests? I've seen people run 200+ tests in 5-6 seconds. The difference seems to be too large. – Rahul Mar 18 '13 at 07:41
  • I've had the Ruby VM take something like 3-4 seconds just to start up, and that's on recent hardware. – beatgammit Mar 18 '13 at 07:43
  • That's correct. But doesn't Rspec exclude that time from its log? So 5 seconds should address tests only right? – Rahul Mar 18 '13 at 07:55
  • I agree that's slow for just 13 tests, have you tried removing the database cleaner calls just to see if that's the culprit (some of your tests will quite possibly fail, but you may find out where the problem is)? – Sam Peacey Mar 18 '13 at 07:56
  • I thought you were talking about total running time (like `time ruby something`), not RSpec time. In that case, you may have a point. – beatgammit Mar 18 '13 at 07:56
  • Have you tried running your specs individually to see which one is taking the longest? This may give you some clues. – muttonlamb Mar 18 '13 at 08:04
  • @cheeseweasel 5.14 seconds without database cleaner. – Rahul Mar 18 '13 at 08:12
  • @muttonlamb Only 1 test file. Gist [here](https://gist.github.com/recklessrahul/5185722) – Rahul Mar 18 '13 at 08:17
  • Rather then running them individually, you can run with the -p flag, which will tell you how long the 10 (by default, you can change this) slowest examples take. – Sam Peacey Mar 18 '13 at 08:20
  • That's fantastic. one of my tests was taking 3 seconds to run. Thanks @cheeseweasel. Could you please convert this to an answer :) – Rahul Mar 18 '13 at 08:23
  • Okay great, glad to hear it helped. :) – Sam Peacey Mar 18 '13 at 08:24

2 Answers2

15

You can profile your specs by running rspec with the -p / --profile flag:

rspec spec -p [-drb, and whatever else]

This will list the 10 slowest examples with their execution time. You can change the default of 10 by providing an optional count to the -p flag. More info by using rspec --help

Sam Peacey
  • 5,964
  • 1
  • 25
  • 27
1

In my case problem was in RSpec running in development ENV, not in test. I fixed it by adding ENV['RAILS_ENV'] ||= 'test' as a first line in spec_helper.rb - otherwise it didn't worked.

Also I must recommend very useful gem for profiling code - test-prof

Stejzyy
  • 41
  • 3