If you develop a gem which integrates with Rails you may want to test against multiple versions of it. My solution to this to use one page Rails applications with the appraisals gem and load the applications based on the actual gem version. Let me show you an example:
Than run `bundle install` and `rake appraisal:install` to generate the gemfile.
The official Rails guide advises to use a `dummy` Rails app for testing but in their guide it is a structured setup and I think it is better to keep everything in one file in this scenario so we will create a one file Rails application:
# test/apps/rails4.rbrequire"rails"require'rails/all'require'action_view/testing/resolvers'require'rails/test_help'require'example'# our gemmoduleRails4classApplication<Rails::Applicationconfig.root=File.expand_path("../../..",__FILE__)config.cache_classes=trueconfig.eager_load=falseconfig.serve_static_assets=trueconfig.static_cache_control="public, max-age=3600"config.consider_all_requests_local=trueconfig.action_controller.perform_caching=falseconfig.action_dispatch.show_exceptions=falseconfig.action_controller.allow_forgery_protection=falseconfig.active_support.deprecation=:stderrconfig.middleware.delete"Rack::Lock"config.middleware.delete"ActionDispatch::Flash"config.middleware.delete"ActionDispatch::BestStandardsSupport"config.secret_key_base='49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk'routes.appenddoget"/"=>"welcome#index"endendendclassWelcomeController<ActionController::BaseincludeRails.application.routes.url_helperslayout'application'self.view_paths=[ActionView::FixtureResolver.new("layouts/application.html.erb"=>'<%= yield %>',"welcome/index.html.erb"=>'Hello from index.html.erb',)]defindexendendRails4::Application.initialize!
Than write an integration test which uses this controller:
# test/integration/welcome_controller_test.rbrequire'test_helper'classWelcomeControllerTest<ActionController::TestCasetest"should get index and our gem should do it's job"doget:indexassert_response:success# do your gem specific assertionendend
If we run `rake appraisal` now it will run this test and it will pass. Next step is to create a Rails 3 test app. First we need to setup the appraisal for that:
# test/apps/rails3_2.rbrequire'rails/all'require'action_view/testing/resolvers'require'rails/test_help'require'example'# our gemclassRails3_2<Rails::Applicationconfig.root=File.expand_path("../../..",__FILE__)config.cache_classes=trueconfig.eager_load=falseconfig.serve_static_assets=trueconfig.static_cache_control="public, max-age=3600"config.consider_all_requests_local=trueconfig.action_controller.perform_caching=falseconfig.action_dispatch.show_exceptions=falseconfig.action_controller.allow_forgery_protection=falseconfig.active_support.deprecation=:stderrconfig.middleware.delete"Rack::Lock"config.middleware.delete"ActionDispatch::Flash"config.middleware.delete"ActionDispatch::BestStandardsSupport"config.secret_token="49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk"routes.appenddoget"/"=>"welcome#index"endendclassWelcomeController<ActionController::BaseincludeRails.application.routes.url_helperslayout'application'self.view_paths=[ActionView::FixtureResolver.new("layouts/application.html.erb"=>'<%= yield %>',"welcome/index.html.erb"=>'Hello from index.html.erb',)]defindexendendRails3_2.initialize!
Now if you ru `rake appraisal` your test suite will be run against both versions of Rails'.
The repo for the source of this example: [multiple-rails-test-example](https://github.com/gregmolnar/multiple-rails-test-example)