Testy cache'owania

Co sądzicie - warto testować cache’owanie? Jeśli tak, to czego używacie - czystego frameworka (Test::Unit, RSpec) czy jakichś pluginów? Jeśli nie - dlaczego?

Cholera, nigdy nie przyszło mi do głowy testowanie cache’owania.

Co tak naprawdę chcesz przetestować albo co taki test powinien objąć, pokryć i zapewnić?
Wygaszanie cache’u? Czy to że dane są zeń brane zamiast generowane za każdym razem przez aplikację?

A czy cachowanie nie jest już w Railsach przetestowane? W jaki sposób cachujesz?

Głównie to, że odpowiednie sweepery są ładowane, dostępne i wywoływane kiedy trzeba. Coś w stylu

sweeper.should_receive(:expire_page).with('some_key)

Dokumentacja do sweeperów jest za mało dokładna żebym czuła się pewnie tylko implementując.

Też kiedyś o tym myślałem, ale trzeba by się nieźle nagimnastykować, żeby napisać dobre testy do cache’owania. Zasadniczo cachowanie może wprowadzać istotne błędy (np. zmieniła się zawartość bazy, a fragment strony zawiera nieaktualne dane). Ale jak to zrobić elegancko i szybko to nie mam pojęcia.

EDIT
To, że Railsy testują Sweepery itp. to za mało - przecież my gdzieś mogliśmy zapomnieć powiadomić Sweeper - dlatego IMHO to ma sens.

Według mnie wszystko zależy od skomplikowania takiego cache’owania. Jeżeli jest to proste cache’owanie z użyciem memcached w stylu

<% cache(@post) do %> ... <% end %>
to z reguły nie testuję, ale zdarzały się przypadki, w których pisałem testy do cache’owanych rzeczy. Jak to zrobić? Jeżeli cache’owanie jest ustawione na jakiś konkretny czas, to można użyć np. Timecopa: http://github.com/jtrupiano/timecop. Z pomocą tego gemu można w łatwy sposób zmienić aktualny czas w ruby. Przydaje się nie tylko do cache’owania, ale też np. jeżeli chcemy przetestować czy po tygodniu wyłączy się możliwość komentowania posta.

Jeżeli chodzi o inne rodzaje cache’owania, oparte o sweepy lub o timestamp, to najprościej jest to sprawdzić pisząc testy integracyjne lub testy widoków.

Dokumentacja do sweeperów jest za mało dokładna żebym czuła się pewnie tylko implementując.

Znasz metodę cache’owania z memcached opartą na sprawdzaniu timestampów? Być może część rzeczy mogłabyś w ten sposób cache’ować. Szczerze mówiąc już nie pamiętam kiedy ostatnio używałem sweeperów.

UPDATE:
W serii scaling rails jest video, w którym jest to dość fajnie wytłumaczone.

Nie znam, na czym to polega? Może się przyda, chociaż wygląda na to że bardziej potrzebujemy cache’a opartego o obserwatory modeli.

Chociaż - logika sweeperów rzeczywiście może stać się dość skomplikowana, może lepiej byłoby ustawić cache z krótkim czasem trwania, np. godzina czy kilka - kilkanaście minut? Opłaca się coś takiego?

[quote=drogus]UPDATE:
W serii scaling rails jest video, w którym jest to dość fajnie wytłumaczone.[/quote]
Jest, ale tłumaczy tylko jak używać, nie jak testować.

Testowanie tego jest bardzo proste. Załóżmy, że chcesz założyć cache na stronie, na której wyświetlasz posta z komentarzami. Jako klucz dajesz posta i symbol, żeby nie było konfliktów z innym miejscem, które zależy od posta:

<% cache([@post, :show]) do %> tutaj wyświetlany jest post i komentarze <% end %>
W komentarzu dodajesz post.touch, żeby uaktualnić posta po zmianie komentarza:

[code]class Comment < ActiveRecord::Base
belongs_to :post
after_save :touch_post

def touch_post
post.touch
end
end[/code]
Przetestować to można bardzo łatwo np. w testach integracyjnych:

[code]post = Factory.create(:post)

visit post_path(post)
page.should_not have_css("#comments .comment")

Factory.create(:comment, :post => post, :body => “Wonderful post”)

visit post_path(post)
page.should have_css("#comments .comment")
page.should have_content(“Wonderful post”)[/code]