Ruby è una delle lingue più popolari utilizzate sul web. Stiamo eseguendo una sessione qui su Nettuts + che ti introdurrà a Ruby, così come i grandi framework e strumenti che accompagnano lo sviluppo di Ruby. In questo episodio, imparerai a testare le tue app Sinatra con Cucumber, Capybara e Rspec.
Nel tutorial precedente di questa serie, abbiamo esaminato Rspec e come è possibile eseguire lo sviluppo basato su test con esso. Ho accennato al fatto che, nel prossimo episodio, esamineremo Rspec per testare le app web. Tuttavia, un paio di commentatori hanno affermato che sarebbero interessati a testare con Cucumber, quindi è quello che utilizzeremo per testare una semplice applicazione web. In realtà, useremo parte di Rspec per ottenere la stessa sintassi di matcher che hai visto l'ultima volta, ma l'impostazione di test effettiva è in Cucumber.
Creeremo un'app Sinatra incredibilmente semplice da testare. Per cominciare, creiamo una cartella di progetto e lanciatela in un Gemfile:
Che cosa? Non lo sai
Gemfile
S? Esci da sotto quella roccia e raggiungi l'episodio 8
fonte: rubygems gemma "sinatra" gemma "shotgun" gemma "cetriolo" gemma "capybara" gemma "rspec"
Adesso corri installazione bundle
in quella directory. Con le gemme installate, siamo pronti per partire! (Opzionalmente, se stai usando RVM, potresti installare queste gemme per questo progetto solo eseguendo rvm --rvmrc --creare 1.9.2@cucumber_example
; eseguirlo prima installazione bundle
)
Quindi, apri un file chiamato myapp.rb
; ecco la nostra app super semplice; simula semplicemente un sito che potrebbe consentirti di iscriverti a una newsletter.
richiedere la classe "sinatra / base" MyApp < Sinatra::Base get "/" do erb :index end post "/thankyou" do @name = params["name"] @email = params["email"] erb :thankyou end get "/form" do erb :form end end
Se non hai familiarità con Sinatra, dai un'occhiata alle eccellenti sessioni di Dan Harper Singing with Sinatra; questo ti consentirà di iniziare a giocare con le basi in pochissimo tempo.
Se hai familiarità con Sinatra, vedrai che stiamo creando tre percorsi qui; sulla home page ('/'), rendiamo semplicemente il index.erb
modello (più sui modelli in un minuto). Se otteniamo una richiesta di posta sul percorso /grazie
, prendiamo i valori del nome
e e-mail
parametri e assegnarli a variabili di istanza. Le variabili di istanza saranno disponibili all'interno di qualsiasi modello che renderizziamo, il che risulta essere thankyou.erb
. Finalmente, a /modulo
, rendiamo il form.erb
modello.
Ora, costruiamo questi modelli. Sinatra guarderà all'interno di una cartella 'views' per i template, quindi mettiamoli lì. Come hai visto myapp.rb
, stiamo usando ERB per rendere i template, quindi saranno, ovviamente, dei template ERB. Se abbiamo un layout.erb
modello, avvolgerà tutti i nostri altri modelli. Quindi, facciamo questo:
L'APPLICAZIONE L'APPLICAZIONE
<%= yield %>
Quella chiamata a dare la precedenza
sarà dove sono inseriti gli altri modelli. E questi altri modelli sono piuttosto semplici:
Questa è la home page
Iscriviti alla nostra newsletter!
Ciao, <%= @name %>. Ora riceverai la nostra email all'indirizzo <%= @email %>
Quindi, c'è la nostra app. Per testarlo manualmente, puoi inserirlo in config.ru
file:
richiedere "./myapp" eseguire MyApp
E poi corri fucile da caccia
nel terminale. Questo avvierà un websever, probabilmente sulla porta 9393. Ora puoi curiosare e testare la nostra app web. Ma vogliamo automatizzare questo test, giusto? Facciamolo!
Cetriolo si autodefinisce come uno sviluppo guidato dal comportamento con eleganza e gioia. Mentre la gioia sembra un po 'inverosimile per me, penso che entrambi saremo d'accordo che l'eleganza, beh, Cucumber ce l'ha fatta.
Poiché lo sviluppo guidato dal comportamento è in parte basato sulla comprensione di ciò che il cliente desidera prima di iniziare la codifica, Cucumber intende rendere i suoi test leggibili dai clienti (AKA, non programmatori). Quindi, vedrai qui che tutti i tuoi test sono scritti in quello che sembra essere un testo semplice (in realtà è Gherkin).
Ricorda come, con Rspec, abbiamo file spec separati per descrivere diverse funzionalità? In Cucumber-speak, quelle sono caratteristiche e appartengono tutte a un? cartella. Dentro quella cartella crea altre due cartelle chiamate? Support? e? step_definitions.?
All'interno del? Supporto? cartella, apri un env.rb
. Questo codice configurerà il nostro ambiente di test. Ecco di cosa abbiamo bisogno:
require_relative "? /? / myapp" richiedono "Capybara" richiedono "Capybara / cetriolo" richiedono "rspec" World do Capybara.app = MiaApp include Capybara :: DSL include RSpec :: Matchers end
Ciò richiede le diverse librerie di cui abbiamo bisogno e utilizza includere
caricare i loro metodi nel nostro ambiente. Cos'è questo Capibara che stiamo usando? Fondamentalmente, è la funzionalità che ci consente di utilizzare la nostra app Web, così da poterla testare. È importante impostare Capybara.app
alla nostra app. Dovrei menzionare che, stavamo facendo questo con un'app Rails, la maggior parte di questa installazione sarebbe stata fatta automaticamente per noi.
(Nota: nello screencast, I include RSpec :: Expectations
unneccessarily; lascialo fuori.)
Okay, scriviamo alcuni test!
Iniziamo con la nostra home page. Apri il file home_pages.feature
(nella cartella? features?) e inizia con questo:
Funzionalità: Viewer visita la Home Page Per leggere la pagina Come visualizzatore voglio vedere la home page della mia app
Questo è un modo comune per avviare un file di funzione; Non sembra davvero un codice, vero? Bene, è Gherkin, un linguaggio specifico del dominio (DSL) che ti consente di descrivere il comportamento del software senza specificare in dettaglio come viene implementato quel comportamento. Ciò che abbiamo scritto finora non funziona in alcun modo, ma spiega lo scopo della funzione. Ecco la struttura generale:
Al fine di [obiettivo] Come [ruolo] voglio [funzionalità]
Non devi seguire quel modello: puoi mettere tutto ciò che vuoi; lo scopo è quello di descrivere la funzione. Tuttavia, questo sembra essere un modello comune.
Segue una lista di scenari che descrivono la funzione. Ecco il primo:
Scenario: Visualizza home page Dato che sono sulla home page Allora dovrei vedere "Questa è la home page".
Ogni scenario può avere fino a tre parti: Dato
S, quando
s, e Poi
S:
Dato
le linee descrivono quale pre-condizione dovrebbe esistere.quando
le linee descrivono le azioni che fai.Poi
le linee descrivono il risultato.Ci sono anche E
linee, che fanno qualunque sia la linea sopra di loro. Per esempio:
Dato che sono sulla home page E sono registrato Quindi dovrei vedere "Bentornato!" E dovrei vedere "Impostazioni"
In questo caso, il primo E
la linea funge da a Dato
linea, e il secondo funge da a Poi
linea.
Ne vedremo alcuni quando
linee a breve Ma adesso, facciamo quel test. Per farlo, corri cetriolo
nel terminale. Probabilmente vedrai qualcosa di simile a questo:
I file di feature Cucumber sono scritti per essere leggibili dai non programmatori, quindi dobbiamo implementare le definizioni di step per passi non definiti. Per fortuna, Cucumber ci fornisce alcuni frammenti per iniziare.
Guardando questi frammenti, puoi vedere come funzionerà. Ad ogni passaggio corrisponde un'espressione regolare. Qualsiasi valore quotato verrà catturato e passato come parametro di blocco. All'interno del blocco, facciamo tutto ciò che ci aspettiamo che accada come risultato di quel passo. Questo potrebbe essere il codice di installazione Dato
passi, alcuni calcoli o azioni in quando
passi e un confronto in Poi
passaggi.
Cucumber caricherà tutti i file nella cartella? Features / step_definitions? per i passaggi, quindi creiamo? sinatra_steps.rb? file e aggiungi questi due passaggi:
Dato / ^ Sono nella home page $ / do visita "/" end Then / ^ Dovrei vedere "([^"] *) "$ / do | text | page.should have_content text end
In questo piccolo frammento, stiamo usando Cucumber, Rspec e Capybara. In primo luogo, abbiamo il cetriolo Dato
e Poi
chiamate di metodo. In secondo luogo, stiamo usando i metodi Capybara visita
(per visitare un URL) e has_content?
. Ma tu non vedi la chiamata a has_content?
perché abbiamo caricato i correttori RSpec, in modo che i nostri test possano essere letti come con Rspec. Se volessimo lasciare fuori RSpec, scriveremmo page.has_content? testo
.
Ora, se corri cetriolo
ancora, vedrai che i nostri test passano:
Aggiungiamo altri due scenari per la nostra home page:
Scenario: Trova la voce sulla home page Dato che sono sulla home page Allora dovrei vedere "LA MIA APP" nel selettore "h1" Scenario: Trova il link al modulo Dato che sono sulla home page Allora dovrei vedere "Iscriviti per la nostra newsletter. " in un link
Questi richiedono altri due Poi
passi, come scoprirai se proverai a farlo. Aggiungi questi a sinatra_steps.rb
:
Quindi / ^ dovrei vedere "([^"] *) "nel selettore" ([^ "] *)" $ / do | text, selector | page.should selettore_selettore, contenuto: fine testo Quindi / ^ dovrei vedere "([^"] *) "in un collegamento $ / do | testo | pagina.should testo_sesto fine
Dovresti essere in grado di dire cosa stanno facendo: il primo cerca il testo all'interno di un determinato elemento nella pagina. Il secondo cerca un collegamento con il testo dato (sì, avresti potuto farlo Quindi dovrei vedere "Registrati?" Nel selettore "a"
, ma volevo dovresti un altro metodo Capybara / Rspec)
Di nuovo, corri cetriolo
; vedrai passare tutti i nostri test:
Apriamo ora? Features / form_page.feature ?; buttale lì dentro:
Funzionalità: Viewer si iscrive alla newsletter Per ricevere il giornalista Come utente del sito Web, desidero essere in grado di iscrivermi alla newsletter Scenario: Visualizza pagina modulo Dato che sono su "/ modulo" Quindi dovrei vedere "Riempi questo modulo per ricevere la nostra newsletter. " Scenario: Compila il modulo Dato che sono su "/ form" Quando inserisco "nome" con "John Doe" e inserisco "email" con "[email protected]" e faccio clic su "Registrati!" Poi dovrei vedere "Ciao, John Doe. Riceverai di nuovo la nostra newsletter via e-mail all'indirizzo [email protected]"
Il primo scenario qui è piuttosto semplice, anche se abbiamo bisogno di scrivere il Dato
passo per è. Probabilmente puoi capire come farlo ora:
Dato / ^ I am on "([^"] *) "$ / do | percorso | visita percorso fine
Il secondo è un po 'più in profondità. Per la prima volta, stiamo usando quando
passi (ricorda, il E
passi che seguono il quando
sono anche i passi quando
gradini). È abbastanza ovvio che quelli quando
i passaggi dovrebbero fare, ma come lo facciamo nel codice Ruby? Per fortuna, Capybara ha alcuni metodi utili per aiutare:
Quando / ^ riempio "([^"] *) "con" ([^ "] *)" $ / do | elemento, testo | fill_in element, con: text end Quando / ^ clicco "([^"] *) "$ / do | element | click_on elemento fine
Stiamo usando il riempire
metodo, che prende il nome o l'attributo id di un elemento nella pagina. Stiamo anche usando clicca su
, che farà clic sull'elemento con il testo, l'id o il valore specificato. Ci sono anche i più specifici click_link
e click_button
. Per saperne di più, controlla il file Leggimi di Capybara. Sfoglia in tutto il? DSL? sezione per vedere più dei metodi che offre Capybara.
Quando corri cetriolo
ora, dovresti ottenere tutti i nostri test, passando:
Renditi conto che ciò che stiamo testando qui è l'interfaccia utente giusta, non il codice sottostante. Se il nostro codice ti ha davvero firmato per la newsletter, dovremmo anche testare il codice che aggiunge il nome e l'indirizzo e-mail al nostro database, ecc. Solo perché vediamo quello che dovremmo vedere, non significa che noi Riceverai davvero la newsletter, giusto? Questo dovrebbe essere testato separatamente.
E questo è testare le app Web con abbinamenti Cucumber, Capybara e Rspec. Come ho detto, controlla i documenti Capybara per ulteriori informazioni!