Guides

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

    File.open('config/database.yml', 'w') do |f| 
      f.write database_yml.to_yaml
    end
  end
end

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]