Caius Theory

Now with even more cowbell…

Running rails tests under CircleCI 2.0 with MariaDB

CircleCI have released their version 2.0 platform, which is based on top of docker and moves the configuration for each project into a config file in the git repository.

They have a bunch of documentation at https://circleci.com/docs/2.0/. Basic gist is the config file lives at .circleci/config.yml and defines which images to run a series of commands in. You can either specify jobs to run in series, or a workflow containing jobs which can depend on each other and/or run in parallel.

The first step is finding a base image that contains ruby, node and chrome/chromedriver so the the app runs, assets compile and rails feature specs work respectively.

The available images for ruby are listed at https://github.com/CircleCI-Public/circleci-dockerfiles/tree/master/ruby/images, and the mariadb images are listed at https://github.com/CircleCI-Public/circleci-dockerfiles/tree/master/mariadb/images. For the ruby images you'll want to use the …-node-browsers image as it has Node.js for assets and Chrome/chromedriver installed for headless browser testing.

So the start of our config file looks something like the following:

version: 2
working_directory: "~/project"
docker:
  - image: "circleci/ruby:2.4.1-node-browsers"
    environment:
      RAILS_ENV: "test"
  - image: "mariadb:10.2.12"
    environment:
      MYSQL_DATABASE: "app_test"
      MYSQL_USER: "root"
      MYSQL_ALLOW_EMPTY_PASSWORD: true
      MYSQL_HOST: "localhost"

Once we have that then we can start on setting up our rails environment to the point we can run tests. First of all we need to install all our ruby dependencies via bundler.

jobs: 
  - run:
      name: "Install ruby dependencies"
      command: "bundle install --path vendor/bundle"

Then we need to install our JS dependencies via yarn, in much the same way as we did for the ruby dependencies.

  - run:
      name: "Install js dependencies"
      command: "yarn install"

Then we need to sort out our database. There's a chance that the docker instance for MariaDB hasn't come up yet, so we can lean on a tool called dockerize to wait for it to be available. Then we can ask rails to go ahead and setup our test database.

  - run:
      name: "Wait for database to be available"
      command: "dockerize -wait tcp://127.0.0.1:3306 -timeout 1m"
  - run:
      name: "Setup database"
      command: "bundle exec rake db:setup"

And then finally we can run our tests as the final step.

  - run:
      name: "Run tests"
      command: "bundle exec rspec"

Putting it all together, we have the following in .circleci/config.yml:

version: 2
working_directory: "~/project"
docker:
  - image: "circleci/ruby:2.4.1-node-browsers"
    environment:
      RAILS_ENV: "test"
  - image: "mariadb:10.2.12"
    environment:
      MYSQL_DATABASE: "app_test"
      MYSQL_USER: "root"
      MYSQL_ALLOW_EMPTY_PASSWORD: true
      MYSQL_HOST: "localhost"
jobs: 
  - run:
      name: "Install ruby dependencies"
      command: "bundle install --path vendor/bundle"
  - run:
      name: "Install js dependencies"
      command: "yarn install"
  - run:
      name: "Wait for database to be available"
      command: "dockerize -wait tcp://127.0.0.1:3306 -timeout 1m"
  - run:
      name: "Setup database"
      command: "bundle exec rake db:setup"
  - run:
      name: "Run tests"
      command: "bundle exec rspec"

May your test runs always be green and your bugs be squished.