Parallelizing Rails Rspec Tests in CircleCI

Kevin McCarthy
2 min readSep 26, 2019

--

TL:DR
update your yml file with the parts in bold and off you go!

version: 2
jobs:
build:
working_directory: ~/my-app
docker:
— image: circleci/ruby:2.5.0-node-browsers
environment:
PGHOST: localhost
PGUSER: my-app
RAILS_ENV: test
— image: circleci/postgres:10.3
environment:
POSTGRES_USER: my-app
POSTGRES_DB: my-app_test
POSTGRES_PASSWORD: “”
parallelism: 3
steps:
— checkout
# Database setup
— run:
name: Create Database
command: bundle exec rake db:create
— run:
name: Load Database Schema
command: bundle exec rake db:schema:load
# run tests!
— run:
name: Run RSpec Tests
command: |
TESTFILES=$(circleci tests glob “spec/**/*_spec.rb” | circleci tests split)
bundle exec rspec — ${TESTFILES}

Why did you do this?

Slow build times on CircleCI slow everything down. The longer it takes for tests to run the more distracted I will get the less likely I’ll be to return when they fail/pass.

Our total CircleCI build time was around 15 minutes. This is a really annoying length of time to be hanging around.

Why parallelising?

I investigated lots of things to make our tests run faster. Some would save us seconds, others maybe a minute or two. Parallelising cut our test time by over 50%. In terms of a solution that was simply throwing money (extra containers cost money on CircleCI) at the problem to get an instant result, parallelising was easiest thing.

Downsides of parallelising

It lets you write slow tests without feeling the penalty. You’re spending money to compensate for slow tests. The danger is you keep writing slower and slower tests and spending more and more money on parallelisation.

What is parallelising?

Instead of CircleCI running through all the tests and running them one at a time, it splits up the tests into different chunks and assigns a different server (container) to run a percentage of them. So instead of running one test at a time its running three tests at a time. Its pretty cool.

Any tricksiness?

Not particularly. As with other infrastructure-y stuff, I find editing yml files has a bit of a hit and hope approach as I don’t know how to test it apart from make the change, push it up to your repository and see if it works. As you can see it took me ten goes to get there but really that wasn’t a very long time compared to the huge gains this change made.

What’s next?

At the moment we’re at 3 parallelism and builds are taking between 7 and 8 minutes. Adding more containers could get us down to between 5 and 6 minute builds. My goal is 5 minute build time as think that’s just long enough for people to not interrupt people’s flow too much.

--

--

Responses (1)