Search code examples
ruby-on-railsrubyrspecspork

Rails project using spork - always have to use spork?


If I am using spork in my rails project and have a spec_helper.rb file like this

require 'spork'

Spork.prefork do
  ...
end

Spork.each_run do
  ...
end

Does it mean I need to ALWAYS have spork running when I run my specs via rspec spec ? Meaning, if I haven't executed $ spork in a terminal window yet, does it mean my specs will not run properly?


Solution

  • No. We have spork in our spec helper and we don't use it a lot of the time, since it slows the tests down overall on larger suites. We only run spork when we're rapidly iterating, running a small subset of the tests repeatedly during TDD. When spork is not running, we simply do not pass the --drb option to RSpec and everything runs without Spork. Obvious Spork is there, but it doesn't get used unless we start it and run our specs with --drb.

    If you don't want the prefork blocks and stuff there, require an environment variable to be set before you execute them, so you can conditionally by-pass them, if they are causing an issue for you.

    EDIT | I've just split our spec helper into multiple files so the prefork block isn't loaded at all when we're not running Spork. It's not needed, but here's how I did it.

    spec_helper.rb loads one of two different files after doing a quick environment check)

    ENV["RAILS_ENV"] ||= 'test'
    
    # Conditional Spork.prefork (this comment is needed to fool Spork's `bootstrapped?` check)
    if /spork/i =~ $0 || RSpec.configuration.drb?
      require File.expand_path("../spec_helper_spork", __FILE__)
    else
      require File.expand_path("../spec_helper_base", __FILE__)
    end
    

    spec_helper_base.rb is just a copy of the original spec_helper without Spork (you can just rename it back if you delete Spork)

    ENV["RAILS_ENV"] ||= 'test'
    
    require File.expand_path("../../config/environment", __FILE__)
    require 'rspec/rails'
    require 'database_cleaner'
    
    # Load all .rb helper files under the support/ directory
    Dir[Rails.root.join("spec/support/**/*.rb")].each { |file| require file }
    
    RSpec.configure do |config|
      # ... the usual stuff ...
    end
    

    And finally spec_helper_spork.rb is just a wrapper around spec_helper_base.rb

    require 'spork'
    
    Spork.prefork do
      require File.expand_path("../../config/environment", __FILE__)
      require 'rspec/rails'
      require 'database_cleaner'
    end
    
    Spork.each_run do
      $rspec_start_time = Time.now
      require File.expand_path("../spec_helper_base", __FILE__)
    end
    

    The only time spec_helper_spork.rb is loaded is if you:

    a) Invoke the spork command b) Run your specs with the --drb option

    This is working fine for me. I can't stress enough though, that it's not needed. Your specs will run fine without spork running provided you don't pass the --drb option anyway. I do like having it completely split out of our spec helper now that I've done this though.