Unsplash Photo: Daniel Alvarez Sanchez Diaz

Run Tests Against Multiple Ruby Versions On CircleCI

Using multiple MRI ruby versions is not very hard. There are some ruby versions that have already been installed, and if you would like to add, for example, 2.2.0-dev you need to have a closer look. CircleCI adds a lot of abilities to run different commands during all processes.

1. Run the same tests against multiple ruby versions for the same platform

dependencies:
  override:
    - 'rvm-exec 2.1.0 bundle install'
    - 'rvm-exec 2.2.0-preview1 bundle install'

test:
  override:
    - 'rvm-exec 2.1.0 bundle exec rake'
    - 'rvm-exec 2.2.0-preview1 bundle exec rake'

circleci-multiple-platform-tests.yaml view raw

It was easy. The main feature that CircleCI uses is [rvm] and it helps us to choose the correct ruby version. There is a list of preinstalled ruby versions. In the first section we install gems for each ruby and in the second we run a test.

2. Install custom ruby version

Before runnung tests against a new version of ruby, we should install it. [rvm] helps us to do that.

dependencies:
  pre:
    - 'rvm install ruby-head'
  
  override:
    - 'rvm-exec ruby-head bundle install'
    #....

test:
  override:
    - 'rvm-exec ruby-head bundle exec rake'
    #....

circleci-multiple-ruby-install.yaml view raw

Now you should see the logs with ruby installation.

3. Jruby + MRI

We already know how to run test for multiple ruby versions. Now let’s add supporting of [JRuby]. Latest version that CircleCI currently supports is jruby-1.7.13. Let’s update our config to use the latest available by rvm.

dependencies:
  pre:
    - 'rvm install jruby'
    #....
  
  override:
    - 'rvm-exec jruby bundle install'
    #....

test:
  override:
    - 'rvm-exec jruby bundle exec rake'
    #....

circleci-multiple-jruby.yaml view raw

Let’s add other options to specify what JVM should use and Jruby options:

machine:
  java:
    version: 'openjdk7'
  environment:
    RAILS_ENV: 'test'
    JRUBY_OPTS: '-J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -J-noverify -X-C -Xcompile.invokedynamic=false --1.9 -J-Xmx1g'

circleci-multiple-jruby_env.yaml view raw

4. What if Java gems are different from MRI

As you know, the real world projects are cruel, and mostly you have different versions of gems or even different gems to support Jruby and MRI. A simple solution is just to add a separate Gemfile for Java. And to update our config file accordingly:

dependencies:
  override:
    - 'rvm-exec jruby bundle install --gemfile Gemfile.java'
    #....

test:
  override:
    - 'BUNDLE_GEMFILE=Gemfile.java rvm-exec jruby bundle exec rake'
    #....

circleci-multiple-bundle.yaml view raw

5. Parallelism

I was tired of waiting for all tests to be finished. And decided to split all processes. I’ve found a good manual and what we have:

machine:
  java:
    version: openjdk7
  environment:
    RAILS_ENV: test
    JRUBY_OPTS: -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -J-noverify -X-C -Xcompile.invokedynamic=false --1.9 -J-Xmx2g

dependencies:
  cache_directories:
    - '~/.rvm/rubies'
    - 'vendor'

  override:
    - >
      case $CIRCLE_NODE_INDEX in
       0)
         rvm-exec 2.1.0 bash -c "bundle check --path=vendor/bundle_2.1 || bundle install --path=vendor/bundle_2.1"
         ;;
       1)
         rvm-exec 2.2.0-preview1 bash -c "bundle check --path=vendor/bundle_2.2 || bundle install --path=vendor/bundle_2.2"
         ;;
       2)
         rvm-exec ruby-head gem install bundler
         rvm-exec ruby-head bash -c "bundle check --path=vendor/bundle_head || bundle install --path=vendor/bundle_head"
         ;;
       3)
         rvm-exec jruby gem install bundler
         rvm-exec jruby bash -c "bundle check --path=vendor/bundle_jruby --gemfile Gemfile.java || bundle install --path=vendor/bundle_jruby --gemfile Gemfile.java"
         ;;
      esac

test:
  override:
    - case $CIRCLE_NODE_INDEX in 0) rvm-exec 2.1.0 bundle exec rake ;; 1) rvm-exec 2.2.0-preview1 bundle exec rake ;; 2) rvm-exec ruby-head bundle exec rake ;; 3) BUNDLE_GEMFILE=Gemfile.java rvm-exec jruby bundle exec rake ;; esac:
        parallel: true

circleci-multiple-parallelism.yaml view raw

You can move these scripts to files.

You can find the final version of circle.yml with some tricks here.

That’s all Folks

Michael Nikitochkin is a Lead Software Engineer. Follow him on LinkedIn or GitHub.

If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories.