还有第三种选择:使用多个 gemfile 和多个虚拟应用程序。
宝石文件
Bundler 有一个有用的选项,名为--gemfile
. 有了它,你可以指定用什么文件代替Gemfile
,它会在同名后生成一个锁文件:
bundle install --gemfile Gemfile.rails3
bundle install --gemfile Gemfile.rails4
这将生成 Gemfile.rails3.lock 和 Gemfile.rails4.lock。因此,这些 Gemfile 可以是您的主要 Gemfile 强制 rails 版本的副本:
source "http://rubygems.org"
gemspec
gem "jquery-rails"
gem "rails", '~>4'
使用虚拟应用程序中的 gemfile
然后你有两个虚拟应用程序,一个用于 rails-3,一个用于 rails-4。要在运行(例如)迁移时使用它们正确的 gemfile:
cd test/dummy_rails3
BUNDLE_GEMFILE=../../Gemfile.rails3 bundle exec rake db:migrate
cd ../dummy_rails4
BUNDLE_GEMFILE=../../Gemfile.rails4 bundle exec rake db:migrate
是的,这可能是最糟糕的部分。但这主要是一次性设置。
使用 rake 中的 gemfile
要在运行测试时指示使用哪个版本,请在 Rakefile 中设置环境变量 BUNDLE_GEMFILE :
#!/usr/bin/env rake
rails_version = ENV[ 'RAILS_VERSION' ] || '4'
if rails_version == '3'
ENV[ 'BUNDLE_GEMFILE' ] = 'Gemfile.rails3'
else
ENV[ 'BUNDLE_GEMFILE' ] = 'Gemfile.rails4'
end
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
我更喜欢让用户传递 RAILS_VERSION 而不是直接传递 BUNDLE_GEMFILE,因为它更容易记住,我们可以只传递“3”或“4”。
从测试中使用正确的虚拟应用程序
最后,在 test_helper 中,根据请求的 rails 版本切换虚拟应用程序:
# Configure Rails Environment
ENV["RAILS_ENV"] = "test"
dummy_app = ENV[ 'RAILS_VERSION' ] == '3' ? 'dummy_rails3' : 'dummy_rails4'
require File.expand_path("../#{dummy_app}/config/environment.rb", __FILE__)
require "rails/test_help"
从您的用户角度
为了让您的用户运行测试,他必须通过使用 BUNDLE_GEMFILE 运行迁移任务来进行一次性设置,这并不那么性感。
但是一旦完成,用户就可以针对 rails-3 和 rails-4 运行测试,而无需在每次想要切换版本时生成 Gemfile,并且您可以在测试应用程序中拥有特定于版本的代码和配置,而无需在if Rails.version >= '4'
任何地方放置语句.
运行规格:
RAILS_VERSION=3 bundle exec rake test
bundle exec rake test # rails-4 is the default in code I wrote
您可以在我的activerecord_any_of gem中看到此方法的示例。