Testing On Different Ruby Versions / Interpreters with rvm
Saturday, September 19th, 2009I’ve been playing with a relatively new tool called rvm lately, and I’m loving it. rvm stands for Ruby Version Manager, and it does an exellent job at allowing different rubies to coexist. I currently have 7 versions installed on my machine:
ruby 1.8.6 ruby 1.8.7 patchlevel 72 (my system's default) ruby 1.8.7 patchlevel 174 ruby 1.9.1 ruby 1.9.2 preview1 jruby 1.3.1 rubinius 0.11.0
rvm makes it ridiculously easy to manage them.
Installing
Let’s start by installing rvm
$ gem install rvm $ rvm-install
and follow the instructions rvm-install gives you. Next, let’s install ruby1.9 (v1.9.1 by default).
$ rvm install 1.9
That’s it! rvm fetches the source, compiles the interpreter, and installs it in its own sandbox in ~/.rvm
For moar awesomes, you can install some non-MRI/YARV interpreters.
$ rvm install jruby $ rvm install rubinius
Switching between versions
$ rvm use 1.9 $ ruby -v ruby 1.9.1p243 (2009-07-16 revision 24175) [i686-linux] $ which ruby /home/mynyml/.rvm/ruby-1.9.1-p243/bin/ruby $ rvm use system #revert to using your system's ruby $ ruby -v ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux] $ which ruby /usr/bin/ruby
This speaks for itself, I believe.
Gems
Because each new version lives in its own sandbox, it starts off almost gemless (rvm pre-installs RubyGems and rake). You can install gems just as you normally would.
$ rvm use 1.9 $ gem install mynyml-every #don't use sudo $ rvm gemdir /home/mynyml/.rvm/gems/ruby/1.9.1 $ gem list *** LOCAL GEMS *** mynyml-every (1.0) rake (0.8.7)
Cross Version Testing
Here’s a rake task that will allow you to run your app’s tests across multiple ruby versions (provided you defined your own test task separately)
namespace(:test) do
desc "Run tests on multiple ruby versions"
task(:portability) do
versions = %w( 1.8.6 1.8.7 1.9 jruby rubinius )
versions.each do |version|
system <<-BASH
bash -c 'source ~/.rvm/scripts/rvm;
rvm use #{version};
echo "-------- `ruby -v` ---------\n";
rake -s test'
BASH
end
end
end
And run with:
$ rake -s test:portability
The reason the task looks hackish is because rvm isn’t a script, but a bash function. This function is loaded automatically when you open up a new shell because of the source line rvm-install added to your .bashrc file, but .bashrc itself isn’t loaded when you use #system. So the rake task first sources that function, and then runs everything else within the same session so that it uses its environment.
[update] As Wayne pointed out in the comments, there is a new rvm idiom that can be used to achieve this:
rvm 1.8.6,1.8.7,1.9,jruby,rubinius rake -s test
The rvm docs have also been updated to include this info.
Links
rvm’s official website has pretty good docs. You can also get a fairly good summary of functionality with
$ rvm help
source: http://github.com/wayneeseguin/rvm/
site/docs: http://rvm.beginrescueend.com/
tracker: https://www.pivotaltracker.com/projects/26822
group: http://groups.google.com/group/rubyversionmanager/