No commit activity in last 3 years
No release in over 3 years
Run rspec tests in parallel
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

 Project Readme

Speedup Test::RSpec by running parallel on multiple CPUs (or cores).
ParallelizedSpecs splits tests into even groups(by number of tests or runtime) and runs each group in a single process with its own database.

Setup Requirements IMPORTANT **OutcomeBuilder Formatter and FailuresFormatter must be enabled when using reruns or some ruby 1.9.3 version will provide false positives. This allows streamlined pass\fail determination and thorough false positive checking while handling unusual pass\fail conditions in some versions of ruby 1.9.3

See FailuresFormatter readme section and set RERUNS to 0 if don't want to allow reruns but are using a ruby 1.9.3 version

Setup for Rails

Install

Rails 3

If you use RSpec: ensure you have >= 2.4

As gem

# add to Gemfile
gem "parallelized_specs", :group => :development

OR as plugin

rails plugin install git://github.com/jakesorce/parallelized_specs.git

# add to Gemfile
gem "parallel", :group => :development

Rails 2

As gem

gem install parallelized_specs

# add to config/environments/development.rb
config.gem "parallelized_specs"

# add to Rakefile
begin; require 'parallelized_specs/tasks'; rescue LoadError; end

OR as plugin

gem install parallel

# add to config/environments/development.rb
config.gem "parallel"

./script/plugin install git://github.com/jakesorce/parallelized_specs.git

Setup

ParallelizedSpecs uses 1 database per test-process, 2 processes will use *_test and *_test2.

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:spec          # RSpec

rake parallel:spec[1] --> force 1 CPU --> 86 seconds
rake parallel:spec    --> have 2 CPUs? --> 47 seconds
rake parallel:spec    --> have 4 CPUs? --> 26 seconds
...

Test by pattern (e.g. use one integration server per subfolder / see if you broke any 'user'-related tests)

rake parallel:spec[4,user,]  # force 4 CPU and run users specs
rake parallel:spec['user|product']  # run user and product related specs

Example output

2 processes for 210 specs, ~ 105 specs per process
... spec output ...

843 examples, 0 failures, 1 pending

Took 29.925333 seconds

Loggers

Even process runtimes

Log test runtime to give each process the same runtime.

Rspec: Add to your spec/parallelized_specs.opts (or spec/spec.opts) :

RSpec 1.x:
  --format progress
  --require parallelized_specs/spec_runtime_logger
  --format ParallelizedSpecs::SpecRuntimeLogger:tmp/parallel_profile.log
RSpec >= 2.4:
  If installed as plugin: -I vendor/plugins/parallelized_specs/lib
  --format progress
  --format ParallelizedSpecs::SpecRuntimeLogger --out tmp/parallel_profile.log

SpecSummaryLogger

This logger logs the test output without the different processes overwriting each other.

Add the following to your spec/parallel_spec.opts (or spec/spec.opts) :

RSpec 1.x:
  --format progress
  --require parallelized_specs/spec_summary_logger
  --format ParallelizedSpecs::SpecSummaryLogger:tmp/spec_summary.log
RSpec >= 2.2:
  If installed as plugin: -I vendor/plugins/parallelized_specs/lib
  --format progress
  --format ParallelizedSpecs::SpecSummaryLogger --out tmp/spec_summary.log

SpecFailuresLogger

This logger produces pasteable command-line snippets for each failed example.

This also stores all failures in this file for later consumption during an optional RERUN process which can rerun all failed specs and potentially change the pass\fail outcome of a build if all specs pass. Enable this formatter

E.g.

rspec /path/to/my_spec.rb:123 # should do something

Add the following to your spec/parallelized_spec.opts (or spec/spec.opts) :

RSpec 1.x:
  --format progress
  --require parallelized_specs/spec_failures_logger
  --format ParallelizedSpecs::SpecFailuresLogger:tmp/failing_specs.log
RSpec >= 2.4:
  If installed as plugin: -I vendor/plugins/parallelized_specs/lib
  --format progress
  --format ParallelizedSpecs::SpecFailuresLogger --out tmp/failing_specs.log

FailuresFormatter

REQUIRED FOR RERUNS Note reruns cause some more false positive handling in multiple spots during runtime and should also include the OutcomeBuilder formatter explained separately which handles these conditions

This formatter captures all needed data about failed examples and stores them in a file for an additional run at the end of the first build. If all specs that failed the first time pass the build will be marked as passed in the exit status. The output location defined below is not optional and if this formatter is used must not be changed.

Use default MAX_RERUNS of 9 or set max number of failed specs to be allowed for reruns by exporting environment variable export RERUNS=10

E.g.

Add the following to your spec/parallelized_spec.opts (or spec/spec.opts) :

RSpec 1.x:
  --format progress
  --require parallelized_specs/failures_rerun_logger
  --format ParallelizedSpecs::SpecFailuresLogger:tmp/parallel_log/rspec.failures
RSpec >= 2.4:
  If installed as plugin: -I vendor/plugins/parallelized_specs/lib
  --format progress
  --format ParallelizedSpecs::SpecFailuresLogger --out tmp/parallel_log/rspec.failures

OutcomeBuilder

RECOMMENDED WITH RERUNS Note reruns cause some more false positive handling in multiple spots during runtime and should also include the OutcomeBuilder formatter

Because previously the pass\fail determination was solely on exit status and now we do things besides always fail on non 0 exits we must handle many other causes of non 0 exit codes that we don't want to start the rerun process if they happen.

E.g.

Add the following to your spec/parallelized_spec.opts (or spec/spec.opts) :

RSpec 1.x:
  --format progress
  --require parallelized_specs/outcome_builder
  --format ParallelizedSpecs::SpecFailuresLogger:tmp/parallel_log/outcome_builder.txt
RSpec >= 2.4:
  If installed as plugin: -I vendor/plugins/parallelized_specs/lib
  --format progress
  --format ParallelizedSpecs::SpecFailuresLogger --out tmp/parallel_log/outcome_builder.txt

TrendingExampleFailures

Create a single * delimited text file with all failed examples failure information No built in interface to populate a database with these

E.g.

Add the following to your spec/parallelized_spec.opts (or spec/spec.opts) :

RSpec 1.x:
  --format progress
  --require parallelized_specs/trending_example_failures_logger
  --format ParallelizedSpecs::SpecFailuresLogger:tmp/parallel_log/trends.log
RSpec >= 2.4:
  If installed as plugin: -I vendor/plugins/parallelized_specs/lib
  --format progress
  --format ParallelizedSpecs::SpecFailuresLogger --out tmp/parallel_log/trends.log

SlowestSpecLogger

creates a text file with any specs taking longer than 30 seconds by default but can be overridden by setting a ENV["MAX_TIME"] var

E.g.

Add the following to your spec/parallelized_spec.opts (or spec/spec.opts) :

RSpec 1.x:
  --format progress
  --require parallelized_specs/slow_spec_logger
  --format ParallelizedSpecs::SpecFailuresLogger:tmp/parallel_log/slowest_specs.log
RSpec >= 2.4:
  If installed as plugin: -I vendor/plugins/parallelized_specs/lib
  --format progress
  --format ParallelizedSpecs::SpecFailuresLogger --out tmp/parallel_log/slowest_specs.log

Tools

selenium_trending_collector.rb

This consumes the text files created by the trender formatter and parses it associates the data and pushes it to a database for storage

Setup for non-rails

sudo gem install parallelized_specs
# go to your project dir
parallelized_specs
# [Optional] use ENV['TEST_ENV_NUMBER'] inside your tests to select separate db/memcache/etc.

[optional] Only run selected files & folders:

parallelized_specs test/bar test/baz/xxx_text_spec.rb

TIPS

  • [RSpec] add a spec/parallel_spec.opts to use different options, e.g. no --drb (default: spec/spec.opts)
  • [RSpec] if something looks fishy try to delete script/spec
  • [RSpec] if script/spec is missing parallel:spec uses just spec (which solves some issues with double-loaded environment.rb)
  • [RSpec] 'script/spec_server' or spork do not work in parallel
  • [RSpec] ./script/generate rspec if you are running rspec from gems (this plugin uses script/spec which may fail if rspec files are outdated)
  • [RSpec] remove --loadby from you spec/*.opts
  • [Bundler] if you have a Gemfile then bundle exec will be used to run tests
  • [SQL schema format] use :ruby schema format to get faster parallel:prepare`
  • [ActiveRecord] if you do not have db:abort_if_pending_migrations add this to your Rakefile: task('db:abort_if_pending_migrations'){}
  • export PARALLEL_TEST_PROCESSORS=X in your environment and parallelized_specs will use this number of processors by default
  • with zsh this would be rake "parallel:prepare[3]"
  • [RERUNS] if you're using reruns formatter also use the outcome builder to make your builds handle syntax issues during example_group generation from rspec and thread crashes more cleanly

Authors

inspired by pivotal labs

based loosely from https://github.com/grosser/parallel_tests

Hereby placed under public domain, do what you want, just do not hold me accountable...
Flattr