We recently worked on a big Rails application with a lot of RSpec tests (mostly integration ones) and we were looking for a way to reduce the test suite execution time.
So we ended up trying
parallel_test gem and it has drastically reduced the suite running time!
ParallelTests splits tests into even groups (by number of lines or runtime) and runs each group in a single process with its own database.
It might not be a magic solution for all projects - all in all, loading multiple Rails applications take some time! - but it worked very well in our case and this is how we set it up.
Add gem to
1 gem 'parallel_tests', group: [:development, :test]
If your computer has, for instance, four cores, ParallelTests will use four databases. Each ParallelTests process will use its own environment variable (
TEST_ENV_NUMBER) to identify which database it’s going to use.
So we need to edit our
1 2 test: database: my_app_test<%= ENV['TEST_ENV_NUMBER'] %>
Create databases and load schema:
1 2 rake parallel:create rake parallel:prepare
Create a new file called
1 2 3 4 5 --color --require spec_helper --format progress --format ParallelTests::RSpec::RuntimeLogger --out tmp/parallel_runtime_rspec.log --format ParallelTests::RSpec::SummaryLogger --out tmp/spec_summary.log
RuntimeLogger will keep track of how long each test takes to run and ParallelTests will use this log to split the tests evenly between processes, so that each process should finish around the same time.
SummaryLogger, instead, will output a nice log for each ParallelTests process.
Now we can run our tests in parallel:
1 rake parallel:spec
We can create a binstub if we feel more comfortable with it:
1 2 3 bundle binstub parallel_tests # use binstub instead of rake task bin/parallel_rspec spec