Did you know that you can navigate the posts by swiping left and right?
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:
bundle gem example
create example/Gemfile
create example/Rakefile
create example/LICENSE.txt
create example/README.md
create example/.gitignore
create example/example.gemspec
create example/lib/example.rb
create example/lib/example/version.rb
Initializing git repo in ~/Github/example
We generated a gem skeleton. Let’s prepare the gem for testing. We need to add some dependencies to the gemspec:
# example.gemspec
...
spec.add_development_dependency 'minitest', '>= 3'
spec.add_development_dependency 'appraisal'
...
Create the test folder with the test helper:
# test/test_helper.rb
require 'bundler/setup'
require 'minitest/autorun'
require 'example'
ENV["RAILS_ENV"] = "test"
ENV['DATABASE_URL'] = 'sqlite3://localhost/:memory:'
require "apps/rails4"
Setup rake to run the tests:
require "bundler/gem_tasks"
require 'rake/testtask'
require 'appraisal'
Rake::TestTask.new do |t|
t.libs = ["test"]
t.pattern = "test/**/*_test.rb"
end
task :default => :test
Create an Appraisal
file:
# Appraisals
appraise "rails-4" do
gem "rails", "4.0.0"
gem "sqlite3"
end
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.rb
require "rails"
require 'rails/all'
require 'action_view/testing/resolvers'
require 'rails/test_help'
require 'example' # our gem
module Rails4
class Application < Rails::Application
config.root = File.expand_path("../../..", __FILE__)
config.cache_classes = true
config.eager_load = false
config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_dispatch.show_exceptions = false
config.action_controller.allow_forgery_protection = false
config.active_support.deprecation = :stderr
config.middleware.delete "Rack::Lock"
config.middleware.delete "ActionDispatch::Flash"
config.middleware.delete "ActionDispatch::BestStandardsSupport"
config.secret_key_base = '49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk'
routes.append do
get "/" => "welcome#index"
end
end
end
class WelcomeController < ActionController::Base
include Rails.application.routes.url_helpers
layout 'application'
self.view_paths = [ActionView::FixtureResolver.new(
"layouts/application.html.erb" => '<%= yield %>',
"welcome/index.html.erb"=> 'Hello from index.html.erb',
)]
def index
end
end
Rails4::Application.initialize!
Than write an integration test which uses this controller:
# test/integration/welcome_controller_test.rb
require 'test_helper'
class WelcomeControllerTest < ActionController::TestCase
test "should get index and our gem should do it's job" do
get :index
assert_response :success
# do your gem specific assertion
end
end
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:
# Appraisals
...
appraise "rails-3_2" do
gem "rails", "3.2.14"
gem "sqlite3"
gem "test-unit"
end
Run rake appraisal:install
. We need to change our test helper to switch beetween the Rails apps based on the Rails version:
# test/test_helper.rb
require 'bundler/setup'
require 'minitest/autorun'
require 'example'
ENV["RAILS_ENV"] = "test"
ENV['DATABASE_URL'] = 'sqlite3://localhost/:memory:'
require "rails"
case Rails.version
when '3.2.14'
require 'test/unit'
require "apps/rails3_2"
when '4.0.0'
require "apps/rails4"
end
Than we need to create the test application:
# test/apps/rails3_2.rb
require 'rails/all'
require 'action_view/testing/resolvers'
require 'rails/test_help'
require 'example' # our gem
class Rails3_2 < Rails::Application
config.root = File.expand_path("../../..", __FILE__)
config.cache_classes = true
config.eager_load = false
config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_dispatch.show_exceptions = false
config.action_controller.allow_forgery_protection = false
config.active_support.deprecation = :stderr
config.middleware.delete "Rack::Lock"
config.middleware.delete "ActionDispatch::Flash"
config.middleware.delete "ActionDispatch::BestStandardsSupport"
config.secret_token = "49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk"
routes.append do
get "/" => "welcome#index"
end
end
class WelcomeController < ActionController::Base
include Rails.application.routes.url_helpers
layout 'application'
self.view_paths = [ActionView::FixtureResolver.new(
"layouts/application.html.erb" => '<%= yield %>',
"welcome/index.html.erb"=> 'Hello from index.html.erb',
)]
def index
end
end
Rails3_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