Remarkable – Rails Anwendungen automatisch testen
Seit über einem Jahr entwickle ich Webanwendungen mit Ruby on Rails. Und seit dieser Zeit schreibe ich Tests für meine Anwendungen. Angefangen von Test::Unit über test/spec bis zu RSpec. Doch selten gingen mir Tests leicht von der Hand. Ständig stelle ich mir die Frage: Wie viel teste ich? Habe ich genug getestet? Teste ich schon Rails Code?
Die verschiedenen Test Frameworks haben ihre Vor- und Nachteile. Test::Unit ist relativ einfach und schnell. test/spec und RSpec hingegen deutlich lesbarer, jedoch auch langsamer. Sie eigenen sich deshalb besser, um die Tests als Dokumentation zu verwenden. Test::Unit und test/spec verwenden für Viewtests den Umweg über die Controller, was sie im Vergleich zu RSpec deutlich langsamer macht. In Rspec testet man jede Schicht des MVC Musters separat. Das Verhalten der jeweils anderen Schichten wird mit Mocks und Stubs simuliert. Integration Tests mit Cucumber testen dann das Zusammenspiel aller Schichten.
Carlos Dandos und José Valims Remarkable ist das mit Abstand großartigste Plugin für Ruby on Rails, was mir seit langem über den Weg gelaufen ist, denn es reduziert Tests auf das nötigste! Man schreibt in unglaublich expressiver Form, was das erwartete Verhalten ist. Das auf RSpec basierende Remarkable testet mit einer Vielzahl von Custom Matchers die Erwartung ab.
Ein Beispiel für ein Model Validation Test in Test::Unit
class UserTest < Test::Unit
def test_user_not_valid_if_name_is_blank
user = User.create
assert user.invalid?
assert_equal :blank, :user.errors[:name]
end
endEin Beispiel für ein Model Validation Test in test/spec
context 'User validations' do
specify 'user should not be valid if name is blank' do
user = User.create
user.should.not.be.valid
user.errors[:name].should == :name
end
endEin Beispiel für ein Model Validation Test in RSpec
describe User do
it 'should not be valid if name is blank' do
user = User.create
user.should_not_be_valid
user.errors[:name].should == :blank
end
endUnd jetzt der gleiche Test mit Remarkable:
describe User do
it { should validate_presence_of(:name) } # RSpec syntax
should_validate_presence_of :name # Remarkable macro syntax
endOk, was musst du tun, um Remarkable verwenden zu können? Falls noch nicht geschen, solltest du das Gem Verzeichnis von Github als Quelle für weitere Gems lokal registrieren:
sudo gem sources -a http://gems.github.comDanach müssen die benötigten Gems installiert werden:
sudo gem install rspec -v 1.2.6
sudo gem install rspec-rails -v 1.2.6
sudo gem install remarkable_railsFür alle, die noch eine Rails Version < 2.2 verwenden müssen zusätzlich den I18n Backport von Sven Fuchs installieren:
sudo gem install svenfuchs-i18nAbschließend müssen im Rootverzeichnis des entsprechenden Rails Projektes noch einige helper scripte generiert werden:
ruby script/generate rspecWelche Matcher bringt Remarkable mit?
- Matcher für alle Validierungen mit allen Optionen
- Matcher für alle Assoziationen mit fast allen Optionen
- Named Scopes und Massenzuweisungsmatchern
- Datenbank Matcher für Indexes usw.
Ein typischer Unit Test mit Remarkable könnte so aussehen:
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe User, 'validations' do
should_validate_presence_of :username, :email, :password
should_validate_length_of :username, :minimum => 6
should_validate_acceptance_of :agreement
end
describe User, 'associations' do
should_have_many :images
should_have_many :posts
should_have_one :profile
end
describe User, 'database' do
should_have_column :activated, :type => :boolean
should_have_index :username
end
describe User, 'named scopes' do
should_have_scope :with_image, :joins => :images
should_have_scope :activated, :conditions => { :activated => true }
endUnd von nun an möchte ich nicht mehr hören, dass testen zu schwer sei. Alles Ausreden!
In diesem Sinne, Test frei.

Neueste Kommentare