I test sono spesso trascurati nella programmazione e lo sviluppo web non è diverso. Molti sviluppatori non si sono ancora resi conto che i test automatizzati possono renderti più produttivo, meno stressato e più sicuro di programmare la prossima funzione. In questo articolo, ci concentreremo sull'utilizzo del selenio per automatizzare i test del browser.
Come sviluppatori web, abbiamo bisogno di test di qualche tipo, perché certamente non vogliamo che le segnalazioni di bug degli utenti delle nostre applicazioni siano il nostro mezzo di test. Vogliamo essere test automatizzato perché il test manuale, anche se a volte un male necessario, è lento, soggetto a errori e noioso. Ripetuti test manuali di un'applicazione Web in più browser possono, francamente, distruggere l'anima! Uno strumento come il Selenio può farti appassionare ai test automatici.
Forse puoi relazionarti a questa esperienza: apri il tuo progetto con l'intento di codificare una nuova funzionalità o di correggere un bug, e ti chiedi, "Potrebbero le modifiche che sto per fare avere effetti collaterali non voluti? Potrò infrangere il mio codice? ?"
Questa paura di apportare modifiche peggiora solo con il progredire del progetto, e spesso rovina il divertimento della codifica.
Ma se hai una buona serie di test automatici e li esegui frequentemente, hai buone probabilità di sapere molto rapidamente se hai rotto il tuo codice. Questo ti dà un senso di sicurezza piuttosto che uno di paura, che ti permette di andare avanti semplicemente con quello che devi fare, sia che stia implementando nuove funzionalità, bug fixing o refactoring. È molto rinfrescante.
Questo è più facile da capire quando hai passato il dolore della programmazione senza buoni test. È allettante pensare: "Voglio solo continuare a scrivere la prossima parte della mia domanda". Questo è spesso il caso quando si lavora su qualcosa di relativamente semplice. Ma come ogni sviluppatore può dirti, le cose possono diventare rapidamente più complesse. All'improvviso è spaventoso modificare il codice, ed è allora che apprezzi davvero un set completo di test per aiutarti.
Ma ridurre la paura è solo un vantaggio. Test ben scritti agiscono per documentare il sistema in fase di sviluppo, e questo promuove meglio una comprensione tra sviluppatori e clienti. Osservando un test dovresti essere in grado di dire esattamente come dovrebbe comportarsi un particolare aspetto del sistema. Questo è un concetto enfatizzato da Behavior-Driven Development (discusso più avanti).
Un'idea importante è che considerare come testare la tua applicazione è importante quanto il modo in cui lo sviluppi. Vale la pena di ripetere: pensare a come testare il tuo sistema è importante quanto il modo in cui scrivi il codice dell'applicazione.
È un cambiamento importante nel modo di pensare, ma una volta che hai deciso di vedere i test automatici come parte fondamentale della programmazione e ne hai raccolto i benefici, non guarderai mai indietro. Mi sono appassionato ai test mentre venivo introdotto al TDD, ma a mio avviso essere infettato da test non è necessariamente un test TDD o unitario. Devi solo aver sperimentato l'enorme valore dei test automatici e sentirti strano nella programmazione se non nella routine di scriverli.
Una volta che sei nella mentalità e hai raccolto i benefici, non guarderai mai indietro
Una risposta a questi argomenti potrebbe essere: "Tutto questo sembra qualcosa che richiederebbe molto tempo, tempo che potrebbe codificare la prossima funzione". Dopotutto, normalmente abbiamo un tempo limitato da dedicare a un progetto. Ed è vero, la creazione e la composizione di test automatici richiede tempo e impegno. Ma la quantità di tempo che risparmia a lungo termine e la qualità migliorata che tende a portare al codice, rendono la routine rigorosa dei test automatizzati che vale l'investimento.
Useremo uno strumento gratuito chiamato Selenium. Il selenio automatizza i browser; simula un utente che interagisce con la tua applicazione Web, esegue clic del mouse, immissione di testo e persino trascina e rilascia (tra le altre cose). Può anche essere usato per controllare cosa viene visualizzato sullo schermo.
Sapere come scrivere buoni test è un'abilità che si sviluppa nel tempo, ma in questo tutorial parleremo di come iniziare con i test del browser usando Selenium.
Se sei nuovo al test, è utile avere un'idea generale dei tipi di test comunemente in uso. Diversi tipi di test sono utilizzati per scopi diversi. Tieni presente che la terminologia che circonda il test è alquanto incoerente: le persone diverse usano lo stesso termine per indicare cose leggermente diverse.
Test unitari sono utilizzati per verificare la correttezza delle singole classi, metodi e funzioni. Il codice che viene esercitato dovrebbe essere tenuto isolato da altre parti del sistema e ciò si ottiene usando sostituti per cose da cui dipende il codice sotto il test. In questo modo, è facile vedere dove si verifica il problema quando un test fallisce. I test unitari tendono ad essere i test più veloci da eseguire e nessun codice coinvolto dovrebbe fare cose come colpire un database o accedere alla rete.
I test unitari non dovrebbero riguardare la verifica che i singoli componenti del sistema funzionino correttamente insieme; è qui che arrivano i test di integrazione.
Basso livello test di integrazione potrebbe occuparsi dell'interazione tra due o tre classi, mentre altri potrebbero verificare che il codice funzioni correttamente con risorse esterne, ad esempio un database o un server HTTP.
Test di sistema, che è dove si inserisce questo tutorial, vengono eseguiti contro l'intero sistema integrato per verificare se i requisiti dell'intero sistema sono soddisfatti. I test di sistema possono riguardare cose come prestazioni e scalabilità, ma il tipo di test su cui ci concentreremo si riferisce al fatto se il sistema si comporta come il cliente si aspetta e implementa le funzionalità che ha specificato. Nei cerchi di sviluppo Agile questi test rientrano nella categoria di test di accettazione.
Il codice di esempio presentato di seguito esegue questo tipo di test. Questi test ci dicono se la nostra applicazione si comporta come vogliamo, dal punto di vista dell'utente. Possiamo utilizzare Selenium per automatizzare test di questo tipo perché può simulare un utente che interagisce con il sistema (e può farlo utilizzando veri browser Web, oltre a sistemi headless come HtmlUnit).
Perché saremo interessati solo a che cosa il sistema fa, e non Come lo fa, saremo impegnati nel test della scatola nera. Vale anche la pena notare che, contrariamente alla maggior parte degli altri tipi di test, i test di accettazione dovrebbero essere scritti in collaborazione con i clienti.
Che tipo di test dovresti usare?
Possiamo utilizzare Selenium per automatizzare i test perché può simulare un utente che interagisce con il sistema
La torta è un tipo di cibo ma la maggior parte delle persone (non io) consiglierei di mangiarlo esclusivamente; si integra piuttosto che sostituisce altro cibo. È importante notare che i vari tipi di test si completano a vicenda anziché essere in competizione. Come menzionato sopra, servono a scopi diversi. Ognuno di loro ha vantaggi e svantaggi e non si escludono a vicenda.
I test a livello di sistema, guidati dalla GUI come gli esempi seguenti tendono ad essere relativamente lenti da eseguire e quindi non forniscono feedback rapidi. Test di questo tipo hanno anche la tendenza a essere fragili, e poiché toccano così tanto del codice dell'applicazione, rintracciare la fonte di un fallimento può essere difficile senza un insieme completo di test unitari e di integrazione. In realtà è una buona idea avere molti più test a livello di unità rispetto al tipo di test a livello di sistema basati su GUI per il quale viene utilizzato Selenium. Questo non vuol dire che i test al selenio non sono utili! Il punto è che nessun tipo di test è sufficiente da solo.
Useremo Selenium 2. In particolare utilizzeremo WebDriver, un componente di Selenium 2. WebDriver sostituisce l'API Remote Control (RC) di Selenium 1 e offre numerosi vantaggi rispetto a RC. Ad esempio, è meglio testare AJAX e ha un'API più pulita, più orientata agli oggetti. Funziona anche in un modo completamente diverso da RC. Anziché utilizzare JavaScript per interagire con una pagina, WebDriver utilizza l'interfaccia di automazione del browser che è specifica per ciascun browser. Il risultato è che simula meglio un utente reale che interagisce con il sito Web sottoposto a test.
Un altro componente di Selenium è IDE, uno strumento di registrazione e riproduzione e plugin per Firefox. Non richiede conoscenze di programmazione ed è utile per i test esplorativi.
I suoi test tendono ad essere più fragili degli script RC e WebDriver e un ovvio grosso inconveniente è che può essere utilizzato solo in Firefox. IDE è inteso come uno strumento di prototipazione e non è raccomandato per seri test.
WebDriver supporta un'ampia varietà di browser tra cui Chrome, IE, iOS e Android. Più avanti esamineremo l'uso dei servizi di test del cloud in modo che i test possano essere eseguiti contro combinazioni di sistemi operativi del browser a cui altrimenti non potreste accedere.
Qui, WebDriver sarà usato con Python, ma sono disponibili un certo numero di collegamenti linguistici, inclusi quelli per Java, C # e PHP. Se non hai familiarità con Python, non temere, dovresti comunque essere in grado di seguire gli esempi in quanto legge più o meno come uno pseudo-codice.
Python ... si legge praticamente come pseudo-codice
Sono disponibili diverse altre interfacce, ma le due parti chiave dell'API WebDriver di cui avremo bisogno sono WebDriver
e WebElement
. Ogni esempio qui sotto funzionerà con a WebDriver
oggetto, che corrisponde al browser e uno o più oggetti di tipo WebElement
, che rappresentano elementi su una pagina.
I metodi per localizzare gli elementi in una pagina (discussi in seguito) sono comuni tra queste due interfacce. D'altra parte, metodi come tag_name
sono disponibili solo su WebElement
. Allo stesso modo ha senso per metodi come get_cookies
e ricaricare
essere disponibile su WebDriver
ma non su WebElement
, e questo è davvero il caso.
È interessante notare che c'è uno sforzo per rendere WebDriver uno standard W3C.
Attualmente Selenium 2 supporta Python 2.6 e Python 2.7, quindi installa uno di questi se è necessario. Per scoprire quale versione hai, al tipo di linea di comando python -V
. Gli utenti Linux e Mac normalmente hanno già Python, ma dovrebbero fare attenzione durante l'aggiornamento della loro versione di Python in quanto il sistema operativo potrebbe dipendere dalla versione del sistema operativo fornita con.
Una volta che hai Python 2.6 o 2.7, il modo migliore per installare i pacchetti è con pip. Una volta che hai pip, per installare il Selenium 2 digita: pip installare -U selenio
. (-U
aggiornerà qualsiasi versione precedente che potresti avere. Potrebbero essere necessari utenti Linux e Mac sudo
).
Per ottenere pip su Windows, consulta questa domanda sull'overflow dello stack.
Useremo anche Firefox, poiché è il browser che funziona con WebDriver pronto all'uso.
Abbiamo bisogno di un'applicazione Web da testare e useremo un semplice gioco di indovinelli numerici. È un programma volutamente semplice. Un'applicazione Web viene spesso testata sul computer di uno sviluppatore utilizzando un server Web di sviluppo eseguito localmente, in quanto ciò è utile per i test prima della distribuzione. Tuttavia, in questo caso eseguiremo test su un'app Web distribuita: http://whats-my-number.appspot.com. Questa sarà l'applicazione in prova (AUT). (Nel caso in cui questo sito non funzioni, prova http://whats-my-number-backup.appspot.com/).
La risposta (scusa per rovinare il divertimento) è 42.
Qualunque sia l'input dell'utente, dovrebbe essere visualizzato un suggerimento. Il programma prevede numeri interi da 0 a 100 (inclusi) e se l'utente immette un valore che non si adatta a questa regola, il suggerimento dovrebbe consigliare questo requisito. Quando l'utente prova un numero intero a indovinare da 0 a 100 che non è corretto, il suggerimento mostrato dovrebbe essere "troppo basso" o "troppo alto". Quando viene inserito 42, "Congratulazioni" dovrebbe essere il suggerimento visualizzato.
Qualcosa su cui ci siamo imbattuti prima è l'idea che un ottimo modo per essere espliciti su come un sistema dovrebbe comportarsi è scrivere test, e gli esempi successivi implicheranno una serie abbastanza completa di test che agiranno per comunicare il comportamento previsto dal sistema. Avremo una forma di documentazione eseguibile.
Avremo una forma di documentazione eseguibile
Una delle grandi cose di un linguaggio come Python è che puoi usare un interprete interattivo. Per eseguire l'interprete interattivo di Python è sufficiente digitare pitone
alla riga di comando, e dovresti vedere il suo prompt (>>>
). In alternativa, per eseguire un file di script, utilizzare python nome_script.py
Ovviamente non è il modo in cui il codice di test viene eseguito, ma quando si inizia semplicemente con l'automazione del browser può essere utile utilizzare l'interprete interattivo e digitare una riga di Python alla volta. In questo modo è più facile capire come WebDriver controlla il browser e simula un utente reale. Sebbene tu possa invece eseguire un file di script e sederti e guardare mentre il Selenium fa il suo lavoro, le cose funzionano a un ritmo molto più veloce che con un utente umano, quindi l'esecuzione di comandi una riga alla volta rende più facile ottenere un buon apprezzamento per cosa i comandi che stai emettendo stanno effettivamente facendo. È un ottimo modo per imparare e sperimentare.
Digitare le seguenti righe di codice al prompt dell'interprete, premendo Invio dopo ciascuna. Il primo passo è eseguire un'importazione:
dal selettore di importazione di selenio
Successivamente, apriamo una finestra del browser e visitiamo l'AUT:
browser = webdriver.Firefox () browser.get ('http://whats-my-number.appspot.com/')
Ora faremo qualcosa che rende questo un test. Python integrato affermare
la dichiarazione può essere usata per verificare che qualcosa sia vero, e in questo caso lo usiamo per verificare che il titolo della pagina sia "Qual è il mio numero". Questo può essere indicato come test del contenuto:
asserire 'Qual è il mio numero?' == browser.title
Poiché il titolo della pagina è corretto, Python ci fornisce semplicemente un altro prompt. Il titolo non era corretto avrebbe significato affermare
lanciare un AssertionError
. Un AssertionError
durante l'esecuzione di un file di script provoca il crash del programma (che è utile).
La prossima parte del nostro test è ciò che la documentazione Selenium chiama un test funzionale. Vogliamo verificare che quando 1 è immesso come ipotesi, il programma risponde con contenuti che includono un suggerimento che indica che l'ipotesi è troppo bassa. Gli esempi successivi riguarderanno più voci utente.
Per fare questo dobbiamo compilare il modulo. Se guardi il codice HTML della pagina del gioco d'ipotesi vedrai che il campo di inserimento del testo ha un nome
attributo con il valore di 'guess'. Questo può essere usato per ottenere un WebElement
oggetto per rappresentare il campo di input:
guess_field = browser.find_element_by_name ('guess')
Ora possiamo digitare l'ipotesi. WebElement
ha un send_keys
metodo:
guess_field.send_keys ( '1')
Potremmo trovare il pulsante di invio e fare clic su di esso, o utilizzare il fornito Sottoscrivi
metodo, ma invece premiamo il tasto Invio:
da selenium.webdriver.common.keys import Keys guess_field.send_keys (Keys.RETURN)
Il modulo viene inviato e la pagina viene ricaricata (AJAX non è in uso) e poiché l'ipotesi è troppo bassa, "L'ipotesi è troppo bassa" dovrebbe essere visualizzata da qualche parte nel corpo del documento. Per verificare questo prima abbiamo bisogno di a WebElement
oggetto che rappresenta l'HTML corpo
:
body = browser.find_element_by_tag_name ('body')
Il testo
proprietà di WebElement
in questo caso rivelerà il testo della pagina. Facciamo uso di ciò in un affermare
dichiarazione:
asserire "La tua ipotesi è troppo bassa" in body.text
Di nuovo, successo, quindi Python ci fornisce semplicemente un altro prompt. Poiché si tratta di un'ipotesi errata, "Congratulazioni" non si vede da nessuna parte:
asserire 'Congratulazioni' non in body.text
Finalmente chiudiamo l'istanza di Firefox che abbiamo usato:
browser.quit ()
Se hai familiarità con la programmazione utilizzando JavaScript e il DOM saprai della necessità di ottenere riferimenti a elementi DOM su una pagina Web e, come abbiamo visto, dobbiamo fare qualcosa di simile qui. Le due situazioni non sono esattamente uguali, tuttavia, piuttosto che ottenere un riferimento a un elemento DOM, otteniamo a WebElement
oggetto che corrisponde a un elemento DOM.
Sopra abbiamo usato
find_element_by_name
, che è utile per gli elementi del modulo, così comefind_element_by_tag_name
. Altri metodi di localizzazione includonofind_element_by_id
efind_element_by_css_selector
. Vedere la documentazione del selenio per l'elenco completo.
Per quanto riguarda le prestazioni, l'utilizzo di un ID di elemento o di un localizzatore di nomi (come abbiamo visto sopra) è il modo migliore per selezionare un elemento. Certo, una volta che abbiamo un WebElement
oggetto che corrisponde all'elemento DOM desiderato è comune voler interagire con esso in qualche modo, che è dove i metodi come send_keys
e clic
sono utili.
I test fragili sono pericolosi perché, se i test a volte falliscono quando in realtà dovrebbero passare, si arriva a ignorare i risultati dei test e l'intero processo di test diventa svalutato.
Nel file zip scaricabile che accompagna questo tutorial, ftests1.py
elenca il codice di prova di esempio sopra nella forma di un file di script. Tuttavia c'è un'omissione: si potrebbe notare che la chiamata a implicitly_wait
, incluso in ftests1.py
, non è stato elencato o discusso.
Se esegui un test su un sistema dieci volte, dovrebbe darti lo stesso risultato ciascuno di questi dieci volte. Tuttavia, i test fragili e inaffidabili del tipo che stiamo facendo sono abbastanza comuni e potreste incontrare questo problema mentre sperimentate il test del selenio. I test fragili sono pericolosi perché, se i test a volte falliscono quando in realtà dovrebbero passare, si arriva a ignorare i risultati dei test e l'intero processo di test diventa svalutato. implicitly_wait è uno strumento molto utile nella lotta contro i test fragili, e da questo punto una chiamata a implicitly_wait
sarà usato in tutto il codice di esempio.
Essendo uno sviluppatore infetto da test, ti consigliamo di conoscere gli strumenti xUnit. Sono disponibili per molti linguaggi di programmazione. unittest è uno strumento xUnit fornito di serie con Python. Può sembrare confuso ma, anche se non stiamo scrivendo test unitari, l'unittest è utile. Ad esempio, l'unittest aiuta a strutturare ed eseguire i test, e i fallimenti dei test portano a messaggi più utili.
La versione di unittest in Python 2.7 ha caratteristiche aggiuntive rispetto alle versioni precedenti (alcune delle quali verranno utilizzate), quindi se stai usando Python 2.6 dovrai installare il backport: pip installa unittest2
Il codice di seguito è una versione più semplice del codice di prova presentato in precedenza.
Come prima, viene controllato il titolo della finestra del browser, 1 viene provato come ipotesi e viene verificata la risposta del programma:
prova: import unittest2 come unittest # per Python 2.6 ad eccezione di ImportError: import unittest da selenium import webdriver da selenium.webdriver.common.keys import Keys class GuessTest (unittest.TestCase): def setUp (self): self.browser = webdriver.Firefox () self.browser.implicitly_wait (3) def tearDown (self): self.browser.quit () def test_should_see_page_title (self): # Brian visita il sito del gioco di ipotesi self.browser.get ('http: // whats-my -number.appspot.com/ ') # Vede che "Qual è il mio numero?" è il titolo della pagina self.assertEqual ('Qual è il mio numero?', self.browser.title) def test_should_correct_hint_from_guess_too_low (auto): # Brian visita il sito del gioco di ipotesi self.browser.get ('http: // whats-my-number.appspot.com/ ') # Digita la sua ipotesi nel campo modulo e preme la chiave di ritorno guess_field = self.browser.find_element_by_name (' guess ') guess_field.send_keys (' 1 ') guess_field.send_keys ( Keys.RETURN) # La pagina viene ricaricata e poiché l'ipotesi è troppo bassa, # 'La tua ipotesi è troppo bassa' viene visualizzato body = self.browser.find_element_by_tag_name ('body') self.assertIn ('Your guess is too low' , body.text) # Dal momento che si tratta di un'ipotesi errata, 'Congratulazioni' non si vede da nessuna parte. self.assertNotIn ('Congratulations', body.text) if __name__ == '__main__': unittest.main ()
Cervello è il nome del nostro "utente robot". Guarda anche ftests2.py
nel file zip che accompagna questo tutorial.
I singoli test sono metodi della classe GuessTest
, che eredita da unittest.TestCase
. Per più di un'idea sul se stesso
la parola chiave e altri aspetti orientati agli oggetti di Python vedono la sessione di Nettuts su Python. I nomi dei metodi di prova devono iniziare con le lettere test
. È essenziale rendere descrittivi i nomi dei metodi.
Certo che affermare
è essenziale per qualsiasi test, ma in realtà piuttosto che usare il affermare
dichiarazione come prima abbiamo accesso ai metodi di asserzione di unittest. In questo caso assertEqual
, assertIn
e assertNotIn
sono utilizzati.
Il impostare
e demolire
i metodi vengono eseguiti prima e dopo ciascuno dei metodi di test, e qui li usiamo per avviare e chiudere un'istanza del browser WebDriver.
Il blocco finale, se __name__ == '__main__': unittest.main ()
, consente di eseguire questo script unittest dalla riga di comando. Per eseguire lo script, vai nella directory che contiene ftests2.py
e scrivi: python ftests2.py
. Fare dovrebbe risultare in un output come questo:
Idealmente, i test dovrebbero fallire "rumorosamente" ma passare "in silenzio", e come puoi vedere è esattamente ciò che sta facendo l'unittest: viene stampato solo un punto per ogni metodo di test che passa. Infine vediamo un benvenuto "OK" (non dovrebbe essere "Ben fatto"?).
Come puoi vedere, il principio "Non ripetere te stesso" è stato violato, in quanto l'URL dell'Aut è nel codice due volte. Un test approfondito consente di refactoring del codice dell'applicazione, ma non dimenticare di refactoring anche il codice di test.
Finora i nostri test hanno comportato solo una supposizione: 1, e chiaramente questo non è molto completo. Il prossimo script farà qualcosa per questo, vedi ftests3.py
nel file zip.
Il
importare
dichiarazioni, dichiarazione di classe,impostare
edemolire
metodi e ilse __name__ == '__main__':
blocco, sono tutti esattamente come l'ultimo esempio. Quindi concentriamoci sulle cose che sono diverse.
Poiché questo è qualcosa che faremo ripetutamente, la compilazione del modulo è stata inserita nel suo metodo di supporto, denominato _enter_guess_hit_return
:
def _enter_guess_hit_return (self, guess): guess_field = self.browser.find_element_by_name ('guess') guess_field.send_keys (guess) guess_field.send_keys (Keys.RETURN)
Un altro metodo di supporto, _unsuccessful_guess
, si occupa di visitare l'AUT, chiamando _enter_guess_hit_return
, e chiamando i metodi di asserzione. Di nuovo, il nostro utente robot potrebbe fare un nome, questa volta chiamiamolo Bertie.
def _unsuccessful_guess (self, berties_guesses, expected_msg): self.browser.get ('http://whats-my-number.appspot.com/') per berties_guess in berties_guesses: self._enter_guess_hit_return (berties_guess) body = self.browser. find_element_by_tag_name ('body') self.assertIn (expected_msg, body.text) self.assertNotIn ('Congratulations', body.text)
Potresti notare quella chiamata _enter_guess_hit_return
e l'esecuzione degli asseriti avviene in un ciclo. Questo perché stiamo ricominciando berties_guesses
, che è una lista. berties_guesses
verrà passato a questo metodo dai metodi di test chiamanti, che passeranno anche in un messaggio previsto, expected_msg
.
Ora per fare uso dei nostri aiutanti nei metodi di test:
def test_should_get_correct_hint_from_guess_too_low (self): berties_guesses = ['0', '01', '17', '23', '041'] expected_msg = 'La tua ipotesi è troppo bassa' self._unsuccessful_guess (berties_guesses, expected_msg) def test_should_get_correct_hint_from_guess_too_high (self ): berties_guesses = ['43', '80', '100'] expected_msg = 'La tua ipotesi è troppo alta' self._unsuccessful_guess (berties_guesses, expected_msg) def test_should_correct_hint_from_invalid_input (self): berties_guesses = ['a', '5a' , 'c7', '1.2', '9.9778', '-1', '-10', '101', 'hkfjdhkacoe'] expected_msg = 'Si prega di fornire un numero intero da 0 a 100' self._unsuccessful_guess (berties_guesses, expected_msg)
Per brevità, è stato eliminato il controllo del titolo della pagina. Naturalmente, ci dovrebbe essere un metodo per verificare che, quando viene fornita l'ipotesi corretta, "Congratulations" venga effettivamente visualizzato, e tu sei invitato a scrivere questo metodo (sarà divertente, lo prometto!).
L'ultimo script di esempio ci dà un buon grado di sicurezza sul fatto che l'AUT funzioni come dovrebbe. Ma supponiamo che il codice dell'applicazione debba ora cambiare. Ad esempio, il cliente desidera una nuova funzionalità, o vogliamo refactoring, o forse i test di unità o di integrazione hanno scoperto un errore che i test a livello di sistema non hanno rivelato (e ora desideriamo risolvere quell'errore). Durante il processo di modifica del codice, i test esistenti dovrebbero essere eseguiti frequentemente in modo che i problemi vengano visualizzati prima piuttosto che dopo.
Simuliamo una modifica al codice dell'applicazione. Una versione modificata del gioco è su http://whats-my-number-broken.appspot.com e se corri ftests3.py
contro questa versione vedrai un errore di test:
test_should_get_correct_hint_from_guess_too_high
sta fallendo. Il test mostra che nella modifica del codice dell'applicazione è stata introdotta una regressione. Eseguiamo regolarmente i test e dobbiamo solo prendere in considerazione le modifiche apportate dall'ultimo passaggio dei test per limitare il problema. In questo modo i test di scrittura ci hanno premiato con un senso di sicurezza, in contrapposizione a un senso di paura.
In genere, le applicazioni Web dovrebbero funzionare correttamente su una vasta gamma di browser, quindi normalmente è meglio testare con tutti i browser su quante più piattaforme è possibile ottenere. Quando viene scoperto un problema con un sistema, non è raro che uno sviluppatore dica: "Bene, funziona sulla mia macchina". Questo spesso equivale a: "Non l'abbiamo testato correttamente". Nel caso del gioco di indovinelli numerici ci si potrebbe chiedere se è richiesto un test cross-browser, ma ovviamente è un sistema volutamente semplice.
I servizi basati su cloud come Sauce Labs possono aiutare. Sauce Labs offre una varietà di combinazioni di browser-OS. Un altro servizio è Testingbot, che offre test su piattaforme mobili.
Come hai visto, stiamo eseguendo test su un sito accessibile pubblicamente, ma per i siti ancora in fase di sviluppo e siti intranet, Sauce Labs offre Sauce Connect e Testingbot offre Tunnel.
I campioni di codice finora sono stati hard-coded per usare Firefox. ftests3_remote.py
, disponibile nel file zip, è una versione migliorata di ftests3.py
che può essere facilmente configurato per funzionare utilizzando una determinata combinazione browser-OS (entro i limiti di ciò che viene offerto da qualsiasi servizio di test cloud che usiamo). La piattaforma, il browser e la versione del browser sono specificati sulla riga di comando quando viene eseguito lo script.
I campioni di codice finora sono stati hard-coded per usare Firefox
Dovrai registrarti per un servizio come Sauce Labs o TestingBot per ottenere una chiave API e modificare il file impostare
metodo (come mostrato nel file) per includere questa chiave. Entrambi i servizi possono essere provati gratuitamente.
ftests3_remote.py
si aspetta che la piattaforma sia il primo argomento della riga di comando, il nome del browser richiesto in secondo luogo e la versione del browser è prevista per ultima. Con riferimento alle combinazioni di SO-browser disponibili per Sauce Lab, potremmo, ad esempio, eseguire lo script come segue:
python ftests3_remote.py LINUX chrome
Nel caso particolare di Chrome non dovrebbe essere specificato alcun numero di versione. Per utilizzare Internet Explorer, poiché il nome del browser è composto da due parole, è necessario utilizzare le virgolette. Ad esempio, eseguiamo i test utilizzando il nostro vecchio amico, IE6:
python ftests3_remote.py XP 'internet explorer' 6
I risultati dei test vengono emessi sul terminale proprio come se si stessero eseguendo i test sulla propria macchina. Tuttavia, è possibile prevedere che questo script venga eseguito più lentamente rispetto ai precedenti script di test di esempio. È interessante notare che Sauce Labs consente di guardare un video di ciascun test in esecuzione una volta completato.
Uno script di shell può essere facilmente creato per essere eseguito ftests3_remote.py
un numero di volte, ogni volta con una combinazione di piattaforma-versione diversa.
In precedenza abbiamo esaminato il bisogno di implicitly_wait
. È interessante notare che il valore è passato a implicitly_wait
come suggerito dal codice di ese