I've got a Rails 3.2.21 app on Ruby 2.1.5 that uses Postgres, Redis as the cache store (config.cache_store = :redis_store
), background workers (mostly for view cache warming) with sidekiq. Russian doll caching used with the cache_digests gem so you end up with cache keys like views/my_lovely_partial/5506949e3754753ad58190924d5b029f
. Running tests with RSpec, Factory Girl and Capybara.
For the test environment I have set up a parallel Redis server, different port to production and dev, and have "config.action_controller.perform_caching = true" in test rb. It's the same redis setup in dev and test apart from the port being different. Testing through either controller spec or feature spec I see the presence of objects cached in Redis, either through the tests themselves or directly viewing the keys in redis-cli.
When I try to test for view partials in Redis I find they are not being cached e.g. In dev environment on the same machine the view partials appear in the redis cache whereas in test they don't - only cached objects appear; this is confirmed by viewing through the redis-cli for both dev and test redis instances. 'render_template' and 'have_content' together with viewing the tested page (Using the 'capybara-screenshot' gem) confirm the content is being served successfully but the partials are not being cached in test.
Gems used specifically in test : rspec-rails, factory_girl_rails, faker, capybara, capybara-screenshot, capybara-user_agent, pry, guard-rspec, launchy, database_cleaner, shoulda-matchers, redis, turn.
I've checked in the spec.rb's that perform_caching is still true; tried temporarily removing pry, guard-rspec, launchy, shoulda-matchers gems but no difference. Tried removing database_cleaner gem, disabling all test cache clearing and ran tests again to find only object caching present in redis, no partials.
test.rb
SmashingSuperApp::Application.configure do
config.cache_classes = true
config.whiny_nils = true
config.consider_all_requests_local = false
config.action_dispatch.show_exceptions = true
config.action_controller.allow_forgery_protection = false
config.action_mailer.delivery_method = :test
config.active_support.deprecation = :stderr
config.action_controller.perform_caching = true
config.cache_store = :redis_store, "redis://localhost:6378/0/cache", { expires_in: 1176.hours }
ENV["REDIS_URL"] ||= "redis://localhost:6378/0"
config.action_mailer.raise_delivery_errors = false
config.active_support.deprecation = :log
config.action_dispatch.best_standards_support = :builtin
config.active_record.mass_assignment_sanitizer = :strict
config.active_record.auto_explain_threshold_in_seconds = 0.5
config.log_tags = [:uuid, :remote_ip]
config.before_initialize do |app|
app.config.paths.add 'app/models', :eager_load => true
end
config.to_prepare do
Dir["#{Rails.root}/app/models/*"].each do |model_name|
require_dependency model_name unless model_name == "." || model_name == ".."
end
end
Rails.application.routes.default_url_options[:host]= 'smashingsuperapp.co.uk:3000'
end
rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'capybara/rails'
require 'capybara-screenshot/rspec'
require 'shoulda/matchers'
require 'faker'
require 'redis'
RSpec.configure do |config|
config.include Rails.application.routes.url_helpers
config.infer_spec_type_from_file_location!
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
Rails.cache.clear # Clear redis cache
end
config.before(:each) do |example|
DatabaseCleaner.strategy= example.metadata[:js] ? :truncation : :transaction
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
Rails.cache.clear # Clear redis cache
end
config.include FactoryGirl::Syntax::Methods
config.after do |example|
if example.metadata[:type] == :feature and example.exception.present?
save_and_open_page
end
end
end
def set_host (host)
default_url_options[:host] = host
Capybara.app_host = "http://" + host
end
spec_helper.rb
require 'capybara/user_agent'
Capybara::UserAgent.add_user_agents(mechanize: 'Mechanize')
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.include Capybara::UserAgent::DSL
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
=begin
config.filter_run :focus
config.run_all_when_everything_filtered = true
config.disable_monkey_patching!
if config.files_to_run.one?
config.default_formatter = 'doc'
end
config.profile_examples = 10
config.order = :random
Kernel.srand config.seed
=end
end
def get_path(path)
parsed_params = Rails.application.routes.recognize_path path
controller = parsed_params.delete(:controller)
action = parsed_params.delete(:action)
get(action, parsed_params)
end
Feature specs use 'visit' and controller specs use 'get' to the correct URL's and render the correct content.
Any pointers as to why partials wouldn't be being cached in this situation very much appreciated. Thanks in advance.