Опционально тестирование кеширования в функциональных тестах Rails 3
Как правило, я хочу, чтобы мои функциональные тесты не выполняли кеширование действий. Rails кажется на моей стороне, по умолчанию config.action_controller.perform_caching = false
в environment/test.rb
. Это приводит к нормальным функциональным испытаниям, не проверяющим кеширование.
Итак, как мне проверить кеширование в Rails 3.
Решения, предлагаемые в этой теме, кажутся довольно хакированными или taylored к Rails 2:
Как включить кеширование страниц в функциональном тесте в рельсах?
Я хочу сделать что-то вроде:
test "caching of index method" do
with_caching do
get :index
assert_template 'index'
get :index
assert_template ''
end
end
Может быть, есть и лучший способ проверить, что кэш был поражен?
Ответы
Ответ 1
Вы можете закончить испытаниями, топающими друг на друга. Вы должны обернуть это, соблюдая при этом и reset его старые значения соответствующим образом. Пример:
module ActionController::Testing::Caching
def with_caching(on = true)
caching = ActionController::Base.perform_caching
ActionController::Base.perform_caching = on
yield
ensure
ActionController::Base.perform_caching = caching
end
def without_caching(&block)
with_caching(false, &block)
end
end
Я также помещал это в модуль, поэтому вы можете просто включить его в свой тестовый класс или родительский класс.
Ответ 2
Решение для rspec:
Добавьте вокруг себя блок вокруг с настраиваемым ключом метаданных.
RSpec.configure do |config|
config.around(:each, :caching) do |example|
caching = ActionController::Base.perform_caching
ActionController::Base.perform_caching = example.metadata[:caching]
example.run
Rails.cache.clear
ActionController::Base.perform_caching = caching
end
end
Добавьте ключ метаданных, когда требуется кеширование.
describe "visit the homepage", :caching => true do
# test cached stuff
end
Ответ 3
Моя версия, которая работает:
RSpec.configure do |config|
config.around(:each) do |example|
caching = ActionController::Base.perform_caching
ActionController::Base.perform_caching = example.metadata[:caching]
example.run
Rails.cache.clear
ActionController::Base.perform_caching = caching
end
end
Кредит Россти, но
- Кэш должен быть очищен между примерами
- Кэш-память не может быть установлена по-разному на примерах, только при запуске в случае, если кто-нибудь задается вопросом.
Ответ 4
Вот мое текущее решение проблемы: В environment/test.rb
я установил
config.action_controller.perform_caching = true
Кроме того, я исправляю обезьяны Test::Unit::TestCase
следующим образом:
class Test::Unit::TestCase
def setup_with_disable_caching
setup_without_disable_caching
disable_caching
end
alias_method_chain :setup, :disable_caching
def disable_caching
ActionController::Base.perform_caching = false
end
def enable_caching(&blk)
ActionController::Base.perform_caching = true
if blk
yield
disable_caching
end
end
end
Это позволяет мне написать следующие тесты:
test "info about caching (with caching)" do
enable_caching do
get :about, :locale => :en
assert_template 'about'
get :about, :locale => :en
assert_template nil
end
end
test "info about caching (without caching)" do
get :about, :locale => :en
assert_template 'about'
get :about, :locale => :en
assert_template 'about'
end
Это не идеально, но работает пока. Меня все еще интересуют лучшие идеи!
Ответ 5
Это не ответ, а несколько ограничений, о которых нужно знать, которые не соответствуют комментариям.
-
Все (удивительные) ответы, основанные на ActionController::Base.perform_caching
, не будут работать для низкоуровневого кэширования (cf этот ответ). Единственный вариант, который у вас есть, - это независимый от модуля параметр config.cache_store
, установленный на :null_store
.
-
Как сказал @viktor-trón, ранее установка cache_store
невозможна между тестами, только при init.
-
Кэш распределяется между средами по умолчанию cache_store
. В результате (i) кеш должен быть очищен перед тестированием, если вы боитесь со своего сеанса разработки, (ii) запуск тестов очищает кеш других сред. Тем не менее, ваша производственная среда должна использовать что-то вроде mem_cache_store
или что-то еще более подходящее для нее, поэтому должно быть хорошо.
В двух первых точках кажется, что тестирование для низкоуровневого кэширования невозможно в качестве примера.