自作のRailsプラグインをGemとして公開するときに、複数バージョンのRailsをサポートしたいことがあります。このような時には、サポートするRubyやRailsなど依存Gemのバージョンを組み合わせて、複数環境でのテストを自動化することが出来ます。その方法をまとめます。
Travis CI
CIにはいくつか種類がありますが、Travis CIを使えば、設定のみで複数のRubyやGemのバージョンを組み合わせてテストを自動化出来ます。Travis CIの基本的な使用方法やGithubリポジトリとの連携方法などについては、多くの情報があるのでここでは割愛します。
複数のRubyバージョンでのテスト
.travis.yml
のrvm
に、対象のRubyバージョンを定義します。
rvm:
- 2.1.10
- 2.2.7
- 2.3.4
- ruby-head
matrix:
# ruby-headはテストの失敗を許容する
allow_failures:
- rvm: ruby-head
上記の例では、Rubyの2.1系、2.2系、2.3系をテストの対象としています。ruby-head
は開発中のRubyバージョンであるため、テストが失敗するケースがあります。そこでallow_failures
により失敗を許容します。
複数の依存Gemバージョンでのテスト
例として、複数のRailsバージョンをテストの対象とします。
まず、Gemがサポートするバージョンを定義したgemspecファイルと、依存Gemバージョン毎にGemファイルを用意します。
# Rubyのバージョンを指定する
s.required_ruby_version = '>= 2.1.0'
# Gemに本当に必要なモジュールのみをgemspecに記述する
s.add_dependency 'railties', '>= 4.2.0', '< 5.1'
s.add_dependency 'activerecord', '>= 4.2.0'
source 'https://rubygems.org'
gemspec path: '../'
gem 'rails', '~> 5.0.0'
source 'https://rubygems.org'
gemspec path: '../'
gem 'rails', '~> 4.2.0'
その上で、.travis.yml
のgemfile
に、対象のGemファイルを定義します。
gemfile:
- Gemfile
- gemfiles/Gemfile.rails-5.0
- gemfiles/Gemfile.rails-4.2
matrix:
exclude:
- rvm: 2.1.10
gemfile: gemfiles/Gemfile.rails-5.0
上記の例では、Railsの4.2系と5.0系をテストの対象としています。Rails5.0はRuby2.2系以上に依存するので、exclude
によりRuby2.1系とRails5.0系の組み合わせをテスト対象から除外しています。
ローカルでのテスト
Gemバージョンに依存する処理の開発時は、ローカルの開発環境でも複数バージョンのテストが通ることを確認する必要があります。そのような時には、環境変数にGemファイルを指定してテストを実行することが出来ます。
※以下はテストにRSpecを使用している場合の例です。適宜読み替えて下さい。
# Rails 5.0でのテスト
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-5.0 bundle exec rspec
# Rails 4.2でのテスト
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-4.2 bundle exec rspec
複数の環境変数(ORMなど)でのテスト
ActiveRecord
とMongoid
など、複数のORMをサポートしているGemでは、各ORMに対してテストを回したいこともあります。そのような場合は、.travis.yml
のenv
に環境変数をセットしてテスト環境を定義します。
env:
- MYGEM_ORM=active_record
- MYGEM_ORM =mongoid
matrix:
exclude:
- env: MYGEM_ORM =mongoid
gemfile: Gemfile
services:
- mongodb
テストコードの中で、環境変数に応じて自分のGemにORMをenv
にセットします。rvm
とgemfile
と同じようにMatrixで条件の組み合わせを定義できます。アプリケーションの中で、環境変数MYGEM_ORM
に応じて使用するORMを切り替える処理が必要です。.travis.yml
のservices
にmongodb
と記述すればCI上でMongoDBを使用出来るようになります。
テスト結果
最終的に記述される.travis.yml
は以下のようになります。
language: ruby
rvm:
- 2.1.10
- 2.2.7
- 2.3.4
- ruby-head
gemfile:
- Gemfile
- gemfiles/Gemfile.rails-5.0
- gemfiles/Gemfile.rails-4.2
env:
- MYGEM_ORM=active_record
- MYGEM_ORM=mongoid
matrix:
exclude:
- rvm: 2.1.10
gemfile: gemfiles/Gemfile.rails-5.0
- rvm: 2.1.10
gemfile: Gemfile
- env: MYGEM_ORM=mongoid
gemfile: Gemfile
allow_failures:
- rvm: ruby-head
fast_finish: true
services:
- mongodb
# 中略
script: bundle exec rspec
ソースコードがGithubリポジトリへPushされると、Travis CI上で自動的に複数環境下でのテストが実行されます。