Mein 'ah-ha!' Momente über das Testen in Ruby und Rails kamen, als ich mich wirklich hinsetzte und die endgültigen Ressourcen zu diesem Thema las, die Bücher Rspec und Cucumber . Ich teilte Ihre anfängliche Verachtung von Gurke, aber dann wurde mir klar, dass ich das Bild aus einem völlig falschen Blickwinkel betrachtete.
Grundsätzlich geht es bei Cucumber um BDD (verhaltensgesteuerte Entwicklung) - Sie verwenden Cucumber, um Ihre Funktionen zu planen und woran Sie als Nächstes arbeiten werden. Hmm, als nächstes möchten Sie, dass Benutzer Beiträge in einem Forum oder etwas anderem bewerben können (um ein Beispiel zu stehlen;)). Also schreiben Sie etwas Einfaches.
Given I am logged in
And I can see the post "BDD is awesome"
When I vote the post up
Then the post should have one more vote
And the page should show a message thanking me for my vote.
Beachten Sie, dass es dort so ziemlich keine Verweise auf Code gibt. Das kommt in deinen Schritten. Wenn Sie Ihren Code umgestalten, müssen Sie möglicherweise Ihre Schrittdefinitionen ändern, aber das Verhalten (Ihre Funktion) muss sich nie ändern.
Jedes Mal, wenn Sie Ihre Gurkenfunktion ausführen, werden Sie so ziemlich durch das Testen der Funktion mit TDD (Test Driven Development) geführt. Dies erfolgt auf einer niedrigeren Ebene mit RSpec.
Erster Lauf - meine Definition für den ersten Schritt ist undefiniert. Kopieren Sie den Block, um ihn beispielsweise in user_steps.rb oder sogar session_steps.rb zu definieren, da er sich auf Benutzer und deren Sitzungen bezieht. Wie definieren Sie nun, dass ein Benutzer angemeldet ist? Sie können sie durch den Anmeldevorgang führen.
Given /^I am logged in$/ do
visit login_path
fill_in :name, :with => 'Joe'
fill_in :password, :with => 'Password'
click_button 'submit'
end
Sollte alles glücklich sein. Zweiter Schritt.
Given /^I can see the post "(.+)"$/ do |name|
visit post_path(Post.find_by_name(name))
end
Wieder ziemlich einfach. Beachten Sie, dass wir das Verhalten nicht ändern müssen, wenn wir unseren Anmeldevorgang vollständig wiederholen oder wie unsere Beiträge definiert und angezeigt werden. Dritter Schritt.
When /^I vote the post up$/ do
pending
end
Hier fangen Sie an, über neue Funktionen zu sprechen, aber Sie wissen noch nicht genau, wie es funktionieren wird. Wie stimmst du einen Beitrag ab? Sie können auf ein Bild von +1 oder etwas klicken, das einen Ajax-Beitrag an einen Controller sendet, der JSON zurückgibt, oder auf ein ähnliches. Jetzt können Sie mit reinen Rspec-Tests beginnen.
- Testen Sie Ihre Ansicht, um sicherzustellen, dass das Bild +1 angezeigt wird.
- Testen Sie Ihren Controller, ob er sich korrekt verhält, wenn er eine bestimmte Ajax-Anfrage im richtigen Format erhält (sowohl die glücklichen als auch die unglücklichen Pfade - was passiert, wenn eine ungültige Post-ID empfangen wird? Was passiert, wenn der Benutzer seine 25 Upvotes an einem Tag aufgebraucht hat? Erhöht es die Anzahl der Stimmen korrekt?)
- Testen Sie Ihr Javascript so, dass es korrekt reagiert, wenn ein JSON-Blob im richtigen Format angezeigt wird (aktualisiert es das + 1-Bild, um anzuzeigen, dass es verwendet wurde? (Denken Sie hier an Google+ ...) Zeigt es die Dankesnachricht an? Usw. )
All dies hat keinen Einfluss auf das Verhalten. Wenn Sie jedoch mit den Tests auf niedrigerer Ebene fertig sind, ist es trivial, die Schrittdefinition für die Abstimmung eines Beitrags einzugeben. Es könnte so einfach sein wie click_link '+1'
. Der Rest der Schritte sind Testergebnisse, was wiederum einfach zu bewerkstelligen sein sollte. Und wenn Sie fertig sind, wissen Sie, dass Ihre Funktion vollständig und abgeschlossen ist. Wenn sich das erforderliche Verhalten ändert, können Sie Ihre Funktion optimieren, andernfalls können Sie Ihren Implementierungscode in perfekter Sicherheit optimieren.
Ich hoffe das macht Sinn. Es war alles verrückt, aber ich denke, es zeigt den Unterschied zwischen BDD und TDD und warum Gurke und RSpec unterschiedliche Bedürfnisse bedienen.