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]