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'
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'
#....
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'
#....
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'
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'
#....
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
You can move these scripts to files.
You can find the final version of circle.yml
with some tricks here.
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.