Skip to content

Run individual RSpec examples efficiently in parallel across N cores

License

Notifications You must be signed in to change notification settings

willbryant/parallel_rspec

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ParallelRSpec

This gem lets you run your RSpec examples in parallel across across your CPUs. Each worker gets its own database to avoid conflicts.

Installation

Add this to your application's Gemfile:

group :development, :test do
  gem 'parallel_rspec'
end

Or if you use Spring:

group :development, :test do
  gem 'spring-prspec'
end

And then execute:

$ bundle

This version of ParallelRSpec has been tested with RSpec 3.12.

Usage

By default, ParallelRSpec will use four workers. If you would like to use more, set an environment variable:

$ export WORKERS=8

ParallelRSpec runs each worker with its own copy of the test database to avoid locking and deadlocking problems. To create these and populate them with your schema, run:

$ bundle exec rake db:parallel:create db:parallel:prepare

ParallelRSpec will automatically make the database name for each worker based on the name you used for the test environment in config/database.yml. For example, if your normal test database is foo_test, worker 1 will keep using foo_test but worker 2's database will be foo_test2.

You're then ready to run specs in parallel:

$ bundle exec prspec spec/my_spec.rb spec/another_spec.rb

Or if you use Spring:

$ bundle exec spring prspec spec/my_spec.rb spec/another_spec.rb

You may like to make an alias:

$ alias prspec='bundle exec spring prspec'
$ prspec spec/my_spec.rb spec/another_spec.rb

When you change WORKERS, don't forget to restart Spring and re-run the create and populate steps above if necessary.

By default, there's a task called parallel_rspec which will run all specs. To make a custom rake task which uses parallel_rspec with different options, inherit from ParallelRSpec::RakeTask, for example:

  require 'parallel_rspec'

  ParallelRSpec::RakeTask.new(:prspec) do |t|
    ENV['WORKERS'] = '8'
    t.pattern = "spec/**/*_spec.rb"
    t.rspec_opts = "--tag parallel"
    # etc...
  end

If you'd like code to run after parallel_rspec has created each worker, you can specify a block to run:

  ParallelRSpec.configure do |config|
    config.after_fork do |worker_number|
      puts "I am worker #{worker_number}"
    end
  end

You might also want to detect whether your spec suite is running under ParallelRSpec or not:

  do_something unless ParallelRSpec.running?

Limitations

ParallelRSpec can't parallelize the specs in groups that use before(:context) or after(:context) (AKA before(:all) or after(:all)) hooks, since these may mean that there is state shared between examples.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/willbryant/parallel_rspec.

Thanks

  • Charles Horn (@hornc)
  • Roger Nesbitt (@mogest)
  • Erik Paasonen (@erikpaasonen)

License

The gem is available as open source under the terms of the MIT License.

Copyright (c) Powershop New Zealand Ltd, 2015. Copyright (c) Will Bryant, 2023.

About

Run individual RSpec examples efficiently in parallel across N cores

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages