This gem lets you run your RSpec examples in parallel across across your CPUs. Each worker gets its own database to avoid conflicts.
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.
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?
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.
Bug reports and pull requests are welcome on GitHub at https://github.com/willbryant/parallel_rspec.
- Charles Horn (@hornc)
- Roger Nesbitt (@mogest)
- Erik Paasonen (@erikpaasonen)
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.