RSpec e Cucumber ne valgono davvero la pena?


12

So che la maggior parte dei programmatori RoR sta testando i tossicodipendenti e capisco i vantaggi di una grande suite di test, ma quando inizio i test non ottengo mai una suite così grande e mi chiedo sempre "Sto testando nel modo giusto? Ci sono davvero efficienti?". Spesso mi occupo di test di integrazione testando solo il comportamento dell'applicazione.

Innanzitutto, ne vale davvero la pena? Voglio dire, ne vale davvero la pena il tempo speso a scrivere test?

Quindi, utilizzo RSpec, ho scoperto di recente Cucumber, l'ho usato per un po 'ma non so se scrivere tutti questi passaggi valga davvero la pena? So di poter riutilizzare i passaggi ma non so mai se questi passaggi sono troppo completi o meno: ad esempio, ho usato un Given I am logged in as (.+)ma non so se devo dire nella sua definizione Given there's a user called $1perché può duplicare l'utente se mai creato ma non vale la pena fare sempre un passo prima Given I am logged in as (.+). È un bel po 'di codice che forse raramente sarà utile. Suppongo che non ci siano nuovi bug sulle parti testate ogni giorno ... Quindi vale davvero la pena cetriolo rispetto a RSpec?

Risposte:


13

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.


Questo è stato davvero utile per me. Ma ho un'altra domanda: ho avviato un progetto usando RSpec per testare sia i controller che le viste, il codice è coperto per circa il 90% da test. Pensi che ho davvero bisogno di Cetriolo e passare il tempo a scrivere passaggi e scenari adesso? Voglio dire, posso fare tutto ciò con RSpec comunque.
Cydonia7,

@Skydreamer: probabilmente non è necessario, ma potrebbe essere una buona pratica. Finché fai i test, sei sulla buona strada :)
sevenseacat,

10

Testare, secondo me, è un'arte. Fare TDD (usando RSpec o qualsiasi altro framework) inizialmente ti sembra di "perdere tempo". Questo è comprensibile perché non stai scrivendo alcun codice di produzione.

Tuttavia, inizi a vedere i vantaggi di TDD quando devi migliorare la tua base di codice assicurandoti che tutto il resto funzioni ancora. TDD ti aiuta a rilevare gli errori di regressione il più presto possibile. In questo modo mi ha risparmiato giorni di lavoro perché avevo messo a fuoco i test che hanno evidenziato i miei errori.

Inoltre, avere dei test può essere utile per le revisioni del codice perché il tuo revisore può vedere quali scenari stai testando e come il tuo codice deve essere utilizzato.

Una volta entrati nell'altalena di TDD, fare qualsiasi altra cosa sembra sbagliato.


2
+1 anche se parlando per esperienza, "entrare nel vivo del TDD" è uno sforzo erculeo di per sé e molto difficile da fare per la maggior parte degli sviluppatori.
Wayne Molina,

@Wayne M: Concordato. Entrare nel groove TDD è difficile, ma i benefici sono enormi. :)
David Weiser,

È difficile metterlo alla leggera .. sto provando da anni a pensarci :)
Wayne Molina,

Oh sì, ne vale la pena.
sevenseacat,

2

La mia opinione è che tu abbia ragione sul fronte del cetriolo. Scrivere tutti questi passaggi è un sacco di problemi e i benefici non giustificano il dolore. Ho scritto ampiamente sui sei svantaggi dell'utilizzo di Cucumber qui: perché preoccuparsi dei test sui cetrioli?

I test unitari e i test di integrazione regolari, eseguiti con Rspec o Test :: Unit hanno molto senso, ma per fortuna questi sono molto più veloci da scrivere rispetto ai test Cucumber. Per uno puoi usare il puro Ruby invece di dover combattere la sintassi volgare e imbarazzante di Gherkin.


2
Posso tranquillamente dire che non sono d'accordo con tutti i tuoi punti sui test del cetriolo. * Non interrompe i buoni editor di testo (my gedit lo evidenzierà e lo completerà automaticamente), * non dovresti copiare alcun setup di test dall'impostazione Rspec esistente all'installazione di Cucumber (i due set di test funzionano a livelli molto diversi di granularità), * se non puoi essere coerente nel nominare le tue pagine che non è colpa di Cucumber (Rails non ti permetterà di chiamare percorsi diversi in giorni diversi, quindi perché Cucumber?) (continua)
sevenseacat

1
* Dici qual è la convenzione sui file step ma poi dici che non sapresti dove cercare per seguire la convenzione? Perché la promozione di un post dovrebbe essere diversa da post_steps.rb? * Le tue funzionalità non dovrebbero essere codice, quindi la prolissità è irrilevante - le tue funzionalità sono documentazione su come si comporta la tua app; * E infine, posso solo criticare il "scoraggiamento del riutilizzo del codice" se lo stai facendo in modo sbagliato .
sevenseacat,

2

Quello che credo personalmente è quello RSpec testing is a definite must. Diciamo ad esempio che si desidera scrivere una nuova funzionalità e che ha anche riferimenti ad altre funzionalità e che potrebbe essere referenziata con altri moduli o metodi. Quindi, come puoi assicurarti che ciò che stai scrivendo non stia rompendo nessun'altra parte dell'applicazione?

Supponiamo che tu abbia una grande applicazione e che tu abbia codificato qualcosa di banale rispetto all'applicazione complessiva, eseguirai di nuovo il test dell'intera applicazione facendo clic su ogni collegamento nell'applicazione per assicurarti che funzioni ogni volta che cambi una singola riga di codice?

Tuttavia, credo che i test sui cetrioli non siano indispensabili. Penso che i test di integrazione che utilizzano RSpec stesso abbiano più senso fino a quando non è necessario che i test vengano controllati dal cliente. Quale nella mia esperienza è RARO. Se il tuo team è composto interamente da sviluppatori, penso che dovresti piuttosto sostituire i passaggi di Cucumber per il test delle funzionalità di RSpec. E penso che dopo RSpec 3 DSL, i test siano praticamente leggibili.

Es:

Definizione del passaggio del cetriolo:

Given /^I am logged in$/ do
  visit login_path
  fill_in :name, :with => 'Joe'
  fill_in :password, :with => 'Password'
  click_button 'submit'
end

Test di funzionalità RSpec:

feature 'Given the user is logged in' do
      visit login_path
      fill_in :name, :with => 'Joe'
      fill_in :password, :with => 'Password'
      click_link_or_button 'submit'
end

Penso che invece di avere le funzionalità Cucumber, le funzionalità RSpec facciano la stessa cosa senza il mal di testa aggiuntivo di scrivere altre definizioni di passaggi.

A parte questo, è anche puramente una tua preferenza.

Spero che questo possa aiutarti a capire un po '.


0

A mio avviso, la prima cosa è distinguere tra pratiche e strutture concrete. Cetriolo non è BDD, RSpec non è TDD.

Se vuoi testare il tuo sistema RSpec è un buon strumento, puoi fare TDD o BDD con RSpec, infatti TDD e BDD sono la stessa cosa. Qualcuno dice "BDD ha fatto il TDD nel modo giusto" e sono totalmente d'accordo, BDD si occupa principalmente di testare caratteristiche / comportamenti anziché testare metodi / classi. In effetti il ​​TDD che Kent Beck descrive sulle sue caratteristiche, ma BDD aiuta molte persone a comprendere questa differenza chiave ed è un grande contributo di Dan North alla comunità di sviluppo.

Usa Cetriolo se ritieni di aver bisogno di uno strumento migliore per comunicare con gli uomini d'affari, ad esempio se i cetrioli consentono ai tuoi uomini d'affari o al Product Owner di aiutare il team a scrivere o rivedere scenari. Ad altre persone piace il cetriolo perché questi scenari sono davvero un'ottima documentazione dal vivo di un sistema, se ritieni di aver bisogno di questo tipo di documentazione prova il cetriolo.

In sintesi:

  • Se vuoi fare TDD / BDD tu stesso o il tuo team -> prova RSpec
  • Se desideri un modo migliore per comunicare con le aziende con storie utente e scenari -> prova il cetriolo
  • Se vuoi una documentazione live delle funzionalità del tuo sistema -> prova il cetriolo.

Naturalmente gli ultimi due hanno un costo elevato associato, devi valutare se ne hai davvero bisogno e ne vale la pena, questo ovviamente dipende totalmente dal tuo progetto e dal tuo ambiente e dalla decisione che spetta a te.

Ma ricorda sempre che RSpec e Cucumber sono solo strumenti e gli strumenti risolvono problemi concreti, quale problema vuoi risolvere ?, poniti questa domanda e probabilmente sei in una posizione migliore per selezionare lo strumento giusto. Sii un programmatore migliore per prendere queste decisioni e non per usare X / Y framework / tool / library / technology.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.