Il mio "ah-ah!" I momenti sui test in Ruby and Rails sono arrivati quando mi sono davvero seduto a leggere le risorse definitive sull'argomento, i libri Rspec e Cucumber . Ho condiviso il tuo disprezzo iniziale di Cucumber, ma poi mi sono reso conto che stavo guardando la foto da un'angolazione errata.
Fondamentalmente, Cucumber riguarda BDD (sviluppo guidato dal comportamento) - usi Cucumber per pianificare le tue funzioni, su cosa lavorerai dopo. Hmm, dopo vuoi che gli utenti siano in grado di promuovere post su un forum o qualcosa (per rubare un esempio;)) Quindi scrivi qualcosa di semplice.
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.
Nota che non ci sono riferimenti a nulla di tutto ciò che riguarda il codice. Questo arriva nei tuoi passi. Quando si esegue il refactoring del codice, potrebbe essere necessario modificare le definizioni dei passaggi, ma il comportamento (funzionalità) non dovrà mai cambiare.
Ora ogni volta che esegui la tua funzione Cucumber, sarai praticamente guidato su come testare la funzione usando TDD (test driven development). Questo viene fatto a un livello inferiore usando RSpec.
Prima esecuzione: la definizione del mio primo passaggio non è definita. Copia il blocco per definirlo in dire user_steps.rb o anche session_steps.rb perché si riferisce agli utenti e alle loro sessioni. Ora, come definisci che un utente ha effettuato l'accesso? Puoi portarli attraverso il processo di accesso.
Given /^I am logged in$/ do
visit login_path
fill_in :name, :with => 'Joe'
fill_in :password, :with => 'Password'
click_button 'submit'
end
Dovrebbe essere tutto felice. Secondo passo.
Given /^I can see the post "(.+)"$/ do |name|
visit post_path(Post.find_by_name(name))
end
Ancora abbastanza facile. Tieni presente che se eseguiamo nuovamente la procedura di accesso o come vengono definiti e mostrati i nostri post, non è necessario modificare il comportamento. Terzo passo
When /^I vote the post up$/ do
pending
end
Ecco dove inizi a parlare di nuove funzionalità, ma non sai ancora come funzionerà ancora. Come voti un post? È possibile fare clic sull'immagine di un +1 o qualcosa del genere, che invia un post Ajax a un controller, che restituisce JSON o alcuni di questi. Quindi ora puoi passare ai test Rspec puri.
- Testa la tua vista per assicurarti che sia visualizzata l'immagine +1,
- Verifica che il tuo controller si comporti correttamente quando riceve una determinata richiesta Ajax del formato corretto (sia i percorsi felici che quelli infelici - cosa succede se viene ricevuto un ID post non valido? Cosa succede se l'utente ha utilizzato i suoi 25 voti al giorno? Aumenta correttamente il numero di voti?)
- Metti alla prova il tuo javascript che risponde correttamente quando viene dato un BLOB di JSON nel formato corretto (aggiorna l'immagine +1 per mostrare che è stata utilizzata? (Pensando a Google+ qui ...) Mostra il messaggio di ringraziamento? Ecc. )
Tutto ciò non influisce sul comportamento, ma quando hai finito di occuparti dei test di livello inferiore, sarà banale compilare la definizione del passaggio su come votare un post. Potrebbe essere semplice come click_link '+1'
. E il resto dei passaggi sta testando i risultati, che dovrebbero essere ancora semplici da fare. E quando hai finito, allora sai che la tua funzione è completa e finita. Se il comportamento necessario cambia, puoi modificare la tua funzionalità, altrimenti puoi modificare il tuo codice di implementazione in perfetta sicurezza.
Spero che abbia senso. È stato tutto fuori dalla mia testa, ma penso che dimostri la differenza tra BDD e TDD, e perché Cucumber e RSpec soddisfino esigenze diverse.