Setup parallel tests on Semaphore CI

Hi, today I want speak about slow specs. It's very an unpleasant situation when specs run very slowly and spend many time for build (15-20 or more minutes). One way to remedy this situation it's a split specs into groups and running on multiple CPU cores. For this we can use gem parallel_tests.

It's very useful gem and very easy to setup for local machine. But what if we want setup parallel specs on our CI? For example, I use Semaphore CI for my projects, it's a very good tool. For setup parallel specs we should to do a few things.

Step #1. We should add rake task for prepare database config.

namespace :semaphore do
  task :prepare_db_config do
    db_suffix = "<%= ENV['TEST_ENV_NUMBER'] %>"
    database_yml = YAML.load_file('config/database.yml')

    unless database_yml['test']['database'].ends_with?(db_suffix)
      database_yml['test']['database'] += db_suffix
    end'config/database.yml', 'w') do |f| 
      f.write database_yml.to_yaml

This task will be update database config for Semaphore CI, because by Semaphore CI ignore your config for database name and use hashes for database name.

Step #2. Add this line for drop all databases previously created

bundle exec rake semaphore:prepare_db_config

Step #3. Create databases

bundle exec rake parallel:drop

Step #4. And load schema for all created databases

bundle exec rake parallel:load_schema

Step #5. It's finish step, run specs

By default on rails we run specs by rspec - RAILS_ENV=test bundle exec rspec but for parallel_tests we must use other command

RAILS_ENV=test bundle exec rake parallel:spec

By default parallel_tests use 8 threads and 8 databases in you want change number of process you should add [n] to end of each command, where n - number of process

For example you want use only 5 process, config will be like this:

bundle exec rake parallel:drop[5]
bundle exec rake parallel:create[5]
bundle exec rake parallel:load_schema[5]
RAILS_ENV=test bundle exec rake parallel:spec[5]