Speedup Test::Unit + RSpec + Cucumber by running parallel on multiple CPUs(or cores).
Setup for Rails
===============
## Install
### Rails 3
As gem
gem install parallel_tests
# add to Gemfile
gem "parallel_tests", :group => :development
OR as plugin
gem install parallel
rails plugin install git://github.com/grosser/parallel_tests.git
# add to Gemfile
gem "parallel", :group => :development
### Rails 2
As gem
gem install parallel_tests
# add to config/environments/development.rb
config.gem "parallel_tests"
# add to Rakefile
begin; require 'parallel_tests/tasks'; rescue LoadError; end
OR as plugin
gem install parallel
./script/plugin install git://github.com/grosser/parallel_tests.git
## Setup
### 1: Add to `config/database.yml`
test:
database: xxx_test<%= ENV['TEST_ENV_NUMBER'] %>
### 2: Create additional database(s)
rake parallel:create
### 3: Copy development schema (repeat after migrations)
rake parallel:prepare
### 4: Run!
rake parallel:test # Test::Unit
rake parallel:spec # RSpec
rake parallel:features # Cucumber
rake parallel:test[1] --> force 1 CPU --> 86 seconds
rake parallel:test --> got 2 CPUs? --> 47 seconds
rake parallel:test --> got 4 CPUs? --> 26 seconds
...
Test just a subfolder (e.g. use one integration server per subfolder)
rake parallel:test[models]
rake parallel:test[something/else]
partial paths are OK too...
rake parallel:test[functional] == rake parallel:test[fun]
Example output
--------------
2 processes for 210 specs, ~ 105 specs per process
... test output ...
Results:
877 examples, 0 failures, 11 pending
843 examples, 0 failures, 1 pending
Took 29.925333 seconds
Even process runtimes (for specs only)
-----------------
Log test runtime to give each process the same test runtime.
Add to your `spec/parallel_spec.opts` (or `spec/spec.opts`) :
RSpec 1.x:
--format progress
--format ParallelSpecs::SpecRuntimeLogger:tmp/parallel_profile.log
RSpec >= 2.2:
Installed as plugin: -I vendor/plugins/parallel_tests/lib
--format progress
--format ParallelSpecs::SpecRuntimeLogger --out tmp/parallel_profile.log
Setup for non-rails
===================
sudo gem install parallel_tests
# go to your project dir
parallel_test OR parallel_spec OR parallel_cucumber
# [Optional] use ENV['TEST_ENV_NUMBER'] inside your tests to select separate db/memcache/etc.
[optional] Only run selected files & folders:
parallel_test test/bar test/baz/xxx_text.rb
Options are:
-n [PROCESSES] How many processes to use, default: available CPUs
-p, --path [PATH] run tests inside this path only
--no-sort do not sort files before running them
-m, --multiply-processes [FLOAT] use given number as a multiplier of processes to run
-r, --root [PATH] execute test commands from this path
-e, --exec [COMMAND] execute this code parallel and with ENV['TEST_ENV_NUM']
-o, --test-options '[OPTIONS]' execute test commands with those options
-t, --type [TYPE] which type of tests to run? test, spec or features
--non-parallel execute same commands but do not in parallel, needs --exec
-v, --version Show Version
-h, --help Show this.
You can run any kind of code with -e / --execute
parallel_test -n 5 -e 'ruby -e "puts %[hello from process #{ENV[:TEST_ENV_NUMBER.to_s].inspect}]"'
hello from process "2"
hello from process ""
hello from process "3"
hello from process "5"
hello from process "4"
1 Process | 2 Processes | 4 Processes | |
RSpec spec-suite | 18s | 14s | 10s |
Rails-ActionPack | 88s | 53s | 44s |