Ruby on Rails用のGemを開発する際、いくつかのRailsのバージョンに対応したいことがあると思います。

たとえばRailsの4.xと5.xなどですが、この場合それぞれのRubyや依存Gemのバージョンが変わってくるので、書き方を工夫する必要が出てきます。

この記事では、Travis CIによるテストについてまとめました。

テストするバージョン

この記事では、次の各バージョンでテストすることを想定しています。 Railsの5.xはRubyが2.2.2以上でないと動作しないため、この組み合わせとなっています。

  • Ruby 2.0.0 x Rails 4.2.0
  • Ruby 2.2.2 x Rails 5.0.0

方針

Travis CIには、RubyのバージョンやGemfileを複数指定し、その組み合わせによってテストを行なう仕組みがあります。

これを利用し、Rubyの各バージョンに対するGemfileを用意→それぞれを参照することでテストを行なっていきます。

設定

では、実際の設定について書いていきます。

まず、.travis.ymlにテストするRubyのバージョンとGemfileの一覧を書きます。 また、それぞれのバージョンで含めたくないGemfileをexcludeに定義します。

こうすることで、テストするRubyとGemfileの組み合わせを設定することができます。

.travis.yml:

language: ruby
rvm:
  - 2.0.0
  - 2.2.2
gemfile:
  - gemfiles/Gemfile.ruby-2.0.0
  - gemfiles/Gemfile.ruby-2.2.2
matrix:
  exclude:
    - rvm: 2.0.0
      gemfile: gemfiles/Gemfile.ruby-2.2.2
    - rvm: 2.2.2
      gemfile: gemfiles/Gemfile.ruby-2.0.0

それぞれのGemfileは開発するGemによって違ってくると思いますが、参考までに筆者のAdminiのものを掲載しておきます。

gemfiles/Gemfile.ruby-2.0.0:

source 'https://rubygems.org'

gem 'actionview', '>= 4.2.0', '< 5.0.0'
gem 'activesupport', '>= 4.2.0', '< 5.0.0'

gemspec path: '../'

gemfiles/Gemfile.ruby-2.2.2:

source 'https://rubygems.org'

gem 'actionview', '>= 5.0.0'
gem 'activesupport', '>= 5.0.0'

gemspec path: '../'

おまけ:コントローラのテスト

Railsの4.xと5.xではコントローラのテストの書き方もすこし変わり、ハマりどころがあるので注意が必要です。

Railsの5.xに依存するRSpec 3.5.0から、paramsの渡し方が変わりました。

get :show, { id: 1 }         # 古い方法
get :show, params: { id: 1 } # 新しい方法

この両方に対応するには、これらをラップする関数を定義する必要があります。

spec/support/params_wrapper.rb:

module ParamsWrapper
  def wrapped_params(params = {})
    if Rails.gem_version >= Gem::Version.new('5.0.0')
      { params: params }
    else
      params
    end
  end
end

あとはこれをインクルードします。

spec/spec_helper.rb:

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

RSpec.configure do |config|
  config.include ParamsWrapper
end

こうすることで、前述のgetは次のように書くことができます。 これはRails 4.xと5.xのどちらのテストもパスする方法となります。

get :show, wrapped_params(id: 1)

参考記事