Стратегии испытаний драгоценных камней, чтобы гарантировать, что драгоценный камень работает с Rails 3.x и 4.0?

Я видел несколько примеров фиктивных Rails-приложений (для тестирования, поэтому они живут под тестированием или spec dirs, как правило) для использования с камнем Appraisals, который предположительно работает как с Rails 3.x, так и с Rails 4, но они кажутся хакерскими и не полностью функциональными. Это несколько ожидаемо, так как это урезанный монстр Франкенштейна, который пытается быть совместимым с различными версиями Rails 3, а также с Rails 4.

Я упомянул проекты, которые пытаются провести подобный тест (по состоянию на конец марта 2013 года), например, менее рельсы и рельсы ember-rails, но этот способ тестирования с использованием различных версий Rails выглядит не очень чистым, и нетривиально попытаться отладить нестандартное приложение Rails, особенно в бета-версии Rails.

Было бы здорово иметь более чистый способ тестирования, который позволяет иметь полное приложение Rails для каждой версии Rails для тестирования с помощью этой магии, не так сложно настраивать или поддерживать и не требовать, стандартные пути в местах и ​​т.д.

Каковы доступные стратегии тестирования драгоценных камней с различными версиями Rails (включая, по крайней мере, последние версии Rails 3.1.x, 3.2.x и 4.0.0.beta1), и каковы преимущества и недостатки каждого?

Ответ 1

Несколько вариантов из связанного потока в списке rails-core:

Вариант 1: драгоценный камень оценки и одномачтовое приложение Rails

Кен Коллинз упомянул использование оценки и приложение Rails "dummy":

Я тестирую minitest-spec-rails против 3.0, 3.1, 3,2 и 4.0, используя микс оценки и dummy_app, который минимально настраивает себя в зависимости которая проверяет версию рельсов. Некоторые ссылки:

https://github.com/metaskills/minitest-spec-rails https://github.com/metaskills/minitest-spec-rails/blob/master/test/dummy_app/init.rb

Подобные методы используются в less-rails, ember-rails и high_voltage.

Я использовал аналогичную установку для high_voltage в restful_json (v3.3.0), но с полным Rails-приложением, созданным с 4.0.0-beta1, которое я модифицировал минимально, чтобы работать с Rails 3.1.x/3.2.x.

Обновление: может потребоваться более подробное описание permitters.

Плюсы: Довольно просто. Может тестировать различные версии Rails из командной строки и т.д. Может быть очень минимальной конфигурацией приложений Rails или может использовать полное приложение Rails с незначительными отличиями.

Минусы: повторное использование такого же Rails-приложения для нескольких версий Rails, поэтому некоторые условные обозначения и ненужная конфигурация. (Возможные проблемы с некоторыми файлами, которые не применяются в другой версии Rails и т.д., Но не представляют большой проблемы.)

Вариант 2: Rails версия как переменная среды с единственным Gemfile, одноразовое приложение Rails, полагающееся на travis-ci для тестирования в нескольких версиях

Стив Клабник упомянул решение, которое работает с одним Gemfile, одним полноценным Rails-приложением (хотя в "dummy" dir и без использования оценочной жемчужины, полагаясь на travis-ci для тестирования:

Я хотел бы обсудить эту тему больше, поскольку я это делал за кучу моих драгоценных камней в последнее время. У меня есть два, которые делают это:

Дрейпер: https://github.com/drapergem/draper

LocaleSetter: https://github.com/jcasimir/locale_setter/

В принципе, я внедряю приложение Rails в драгоценный камень, а затем запустить его против нескольких версий Rails на travis через env vars.

Плюсы: Простой. Никакая зависимость от драгоценного камня оценки (не то, что это проблема, но может быть легче поддерживать).

Минусы: повторное использование такого же Rails-приложения для нескольких версий Rails из того, что я могу сказать. Если не использовать travis-ci или что-то, что начинается с чистого gemset (то есть, если выполняется в командной строке), в настоящее время не дифференцируя gemset, так что новый камень может использоваться с более старыми Rails и т.д., Но Стив сказал, что если это вызовет проблему, вы можете просто сдуть замок и переупаковать.

Ответ 2

Есть третий вариант: использование нескольких gemfiles и нескольких фиктивных приложений.

Gemfiles

У Bundler есть полезная опция с именем --gemfile. С его помощью вы можете указать, какой файл использовать вместо Gemfile, и он будет генерировать файл блокировки после того же имени:

bundle install --gemfile Gemfile.rails3
bundle install --gemfile Gemfile.rails4

Это будет генерировать Gemfile.rails3.lock и Gemfile.rails4.lock. Таким образом, эти Gemfiles могут быть копией вашей основной версии Gemfile forcing rails:

source "http://rubygems.org"
gemspec
gem "jquery-rails"
gem "rails", '~>4' 

Использование gemfiles из фиктивных приложений

Затем у вас есть два фиктивных приложения, один для рельсов-3 и один для рельсов-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

Да, это, наверное, самая худшая часть. Но это в основном одноразовая настройка.

Использование gemfiles из rake

Чтобы указать, какую версию использовать во время выполнения тестов, установите переменную среды BUNDLE_GEMFILE в Rakefile:

#!/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 переключите фиктивное приложение в зависимости от того, какая версия рельсов была запрошена:

# 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.