Perché il selenio e il cetriolo non dovrebbero essere usati insieme

In questo post, spiegherò perché credo che sia una cattiva idea scrivere test automatizzati dell'interfaccia utente con selenio e cetriolo.

Il titolo del post menziona Selenium e Cucumber perché sono rispettivamente gli strumenti di automazione del browser e BDD più popolari, tuttavia, il contesto di questo articolo si applica a qualsiasi strumento di automazione dell'interfaccia utente in combinazione con qualsiasi strumento BDD.

Prima di approfondire, esaminiamo alcune informazioni di base.




Cos'è il selenio?

Selenio è uno strumento di test per l'automazione del browser in grado di interagire con gli elementi HTML di un'applicazione web per simulare l'attività dell'utente.

In Selenium WebDriver, possiamo scrivere script in una serie di linguaggi di programmazione e può essere una grande risorsa per più OS e test cross-browser.




Cos'è il cetriolo?

Cetriolo è stato creato per guidare il processo di Behaviour Driven Development (BDD), in modo tale che il cliente possa descrivere i propri requisiti come una serie di esempi chiamati scenari, in file di testo semplice utilizzando il linguaggio Gherkin nel formato Given When Then.

Nel mondo Cucumber, questi file sono chiamati file di funzionalità che vengono esaminati dal team di Scrum per ottenere una chiara comprensione dei requisiti prima di iniziare lo sviluppo vero e proprio.

Una volta che lo sviluppo è in corso, gli sviluppatori e / o il QA scriveranno Step Definitions che sono essenzialmente frammenti di codice che legano gli scenari dai file delle funzionalità al codice di test che esegue azioni contro l'applicazione sotto test.



Selenio e Cetriolo

Sia il selenio che il cetriolo sono ottimi strumenti per i propri scopi, ma se usati insieme, le cose non si sposano bene! Vediamo perché.


Le storie sono generalmente scritte dal punto di vista di un utente, ad esempio:

Caratteristica: Funzionalità di accesso

Come utente del sito web abc.com

Voglio che i clienti possano accedere al sito


In modo che possano visualizzare le informazioni sull'account.

A loro volta, gli scenari nei file delle funzionalità vengono scritti in un modo che descrive il comportamento della funzionalità quando un utente interagisce con il applicazione . Per esempio:

Scenario 1: Login valido

Dato che sono sulla pagina di accesso di abc.com


Quando inserisco credenziali valide

Quindi vengo reindirizzato alla pagina Il mio account

In questo modo puoi aggiungere più scenari per testare diverse combinazioni di dati.

Poiché sia ​​la storia che il file delle caratteristiche sono scritti da un punto di vista di alto livello e poiché vogliamo automatizzare gli scenari, sembra naturale iniziare a scrivere le definizioni dei passaggi in Cucumber che chiamano Selenium per guidare l'applicazione, eseguire le azioni e verificare il risultato.


Ma è qui che si verifica il problema; quando iniziamo a combinare Selenium con Cucumber per scrivere test di interfaccia utente automatizzati.

In tutta onestà, in casi semplici come lo scenario di accesso sopra, le cose si adattano bene insieme e l'approccio sembra plausibile, e in effetti, la maggior parte degli esempi che vedi su Internet, che dimostrano l'uso di selenio e cetriolo, sembrano limitarsi al famoso esempio di accesso.

I lettori di tali blog presumono di poter prendere il semplice scenario di accesso e applicare lo stesso principio a un contesto più ampio di un'applicazione.

Non lasciarti ingannare, però, poiché le cose possono diventare molto aspre con selenio e cetriolo se applicati a una grande applicazione web-based del mondo reale.

Prendiamo un esempio di una pagina dei risultati di ricerca di una tipica applicazione di e-commerce che vende prodotti online. Normalmente la pagina dei risultati di ricerca è piena di funzionalità, come filtri, ordinamenti, elenco di prodotti, possibilità di modificare la ricerca, possibilità di impaginare o caricare automaticamente allo scorrimento, ecc., Come si può vedere nello screenshot qui sotto:

Presumo che ogni funzionalità nella pagina dei risultati di ricerca sia stata aggiunta al sito in modo incrementale utilizzando lo sviluppo agile.

Applicando lo stesso principio del nostro semplice esempio di accesso, man mano che ogni funzionalità viene sviluppata avremmo un rispettivo file di funzionalità riempito con molti scenari diversi. Per esempio:

Nell'iterazione 1 dello sviluppo, viene sviluppato 'Filtra per prezzo', quindi avremmo un file di funzionalità per esso con i propri scenari relativi al filtro del prezzo.

Nell'iterazione 2 dello sviluppo, viene sviluppato 'Filtra per valutazione in stelle', quindi avremmo un file di funzionalità per esso con i propri scenari relativi al filtro di valutazione a stelle e così via per ogni nuova funzionalità.

È importante notare che gli scenari in ogni file di funzionalità sono specifici solo per le rispettive funzionalità. In effetti, questo è il motivo per cui vengono chiamati file di funzionalità perché l'attenzione è su caratteristiche individuali .

Come accennato in precedenza, quando l'applicazione è semplice, possiamo sopravvivere alla sfida di automatizzare gli scenari sull'interfaccia utente con selenio e cetriolo. Tuttavia, con la crescita dell'applicazione e l'aggiunta di nuove funzionalità, aumenta la complessità in quanto potrebbero esserci delle dipendenze tra le diverse funzionalità.

Ad esempio, potrei prima filtrare i miei risultati di ricerca in base al prezzo, quindi applicare un altro filtro per la valutazione a stelle. Ah ... ora abbiamo un problema!

Quale file di funzionalità dovrebbe essere ora incluso in questo scenario? Nel file 'Filter by Star Rating' o 'Filter by Price'? Che ne dici se ora aggiungo uno scenario per applicare un ordinamento ai risultati filtrati per ordinare in base ai voti più alti?

Se uno stakeholder desidera vedere qual è la copertura dei nostri test, in quale file delle funzionalità dovrebbe esaminare? Otterrà il quadro completo della copertura dello scenario leggendo solo uno dei file delle caratteristiche o avrebbe bisogno di leggere tutti i file delle caratteristiche?

Al momento dello sviluppo, quando ogni funzionalità viene sviluppata una per una in ogni iterazione, i file delle funzionalità sarebbero concentrati sulla funzionalità stessa, quindi a un certo punto, quando abbiamo più funzionalità, dobbiamo iniziare a pensare a testarle, non solo isolatamente ma anche scenari creativi in ​​cui combiniamo caratteristiche diverse.

E in effetti, questo è ciò che faranno i veri utenti dell'applicazione. Per prima cosa inseriranno i criteri di ricerca, una volta nella pagina dei risultati di ricerca, potrebbero impaginare, quindi filtrare, quindi ordinare, quindi tornare indietro e così via, e possono eseguire queste azioni in qualsiasi ordine. Non ci sarà un ordine prestabilito degli eventi. Questo è un vero viaggio dell'utente e un vero test del sistema!

La maggior parte dei bug in un'applicazione viene esposta quando una funzionalità stessa è difettosa o quando due funzionalità che funzionano perfettamente in modo isolato non funzionano insieme. Questo è ciò su cui si basa il modello di test Pairwise.

Allora, qual è il grosso problema nell'usare selenio e cetriolo insieme?

Ove possibile, non dovremmo utilizzare la GUI web per la verifica funzionale. La funzionalità di una caratteristica deve essere testata a livello API mediante test di integrazione.

L'interfaccia utente deve essere riservata solo per il controllo dei flussi utente attraverso l'applicazione o per i test end-to-end e per assicurarsi che i moduli o i widget attesi pertinenti siano presenti sulla pagina mentre l'utente naviga da una pagina all'altra.

Un tipico viaggio dell'utente comporterebbe:

1 - Vai alla home page del sito abc.com

2 - Cerca un prodotto dalla homepage

3 - Sfoglia l'elenco dei risultati della ricerca

4 - Applica filtro e / o ordina

5 - Leggi i dettagli del prodotto

6 - Aggiungi il prodotto al carrello

7 - Continua con il check-out ...

Il selenio è eccellente nell'automazione di questi scenari e nel controllo di vari elementi su ogni pagina e, come ho detto sopra, questo è ciò su cui dovremmo concentrarci durante i test a livello dell'interfaccia utente e testando le diverse transizioni di stato.

Come si può vedere, ogni viaggio dell'utente attraverso l'applicazione tocca molte pagine e potenzialmente interagisce con più funzionalità su ogni pagina, e verificheremmo varie cose in ogni fase del viaggio, quindi utilizzando un file delle caratteristiche documentare questi scenari non ha assolutamente alcun senso, perché non stiamo testando una funzionalità, stiamo testando il sistema integrato.

Le cose vanno davvero a forma di pera quando proviamo a scrivere gli scenari end-to-end in un formato dato-quando-allora. Quanti dati avremo? Quanti Thens avremo?

Si potrebbe sostenere che per i test end-to-end potremmo semplicemente usare il selenio da solo senza il cetriolo e avere test automatizzati separati per ciascuna funzione che utilizza selenio e cetriolo. Ancora una volta, non consiglio questo approccio in quanto probabilmente avrai test duplicati e sappiamo quanto siano lenti e fragili i test dell'interfaccia utente, quindi dovremmo mirare ad averne meno, non di più! Inoltre, dovrai comunque occuparti dei test delle dipendenze delle funzionalità.

Sommario

Cucumber è un ottimo strumento per controllare il comportamento di una funzionalità a livello API con test di integrazione in cui ogni funzionalità può essere testata a fondo. Questo strumento dovrebbe essere utilizzato per il test della storia.

Il selenio è un ottimo strumento per automatizzare gli scenari utente a livello dell'interfaccia utente e controllare il comportamento del sistema nel suo insieme, includendo molte storie utente.

Quando arriviamo al test di integrazione del sistema o al test dell'interfaccia utente, è meglio usare Selenium senza il framework Cucumber sottostante poiché provare a scrivere file di funzionalità Cucumber per i viaggi degli utenti, può diventare molto macchinoso e non servirebbe allo scopo per cui è stato creato lo strumento.

Il mio articolo si basa sulla deduzione dei fatti!

  • Se c'è un valore nell'usare il cetriolo, è a livello di funzionalità.
  • Il controllo della funzionalità di una caratteristica è meglio farlo al di fuori dell'interfaccia utente, ad es. Test API.
  • Anche ai test di livello API, il cetriolo fallisce miseramente.
  • I test dell'interfaccia utente dovrebbero coprire scenari utente / aziendali e non singole funzionalità.

Cucumber funziona magnificamente con una visione semplicistica e ingenua di test e scenari, come la funzionalità di accesso preferita da tutti.

Dato che sono nella pagina di accesso
Quando inserisco credenziali valide
Allora dovrei vedere il mio account

Ma qualsiasi tester esperto sa che anche una semplice funzionalità di accesso ha molti molti controlli. Prova a convertire gli assegni in cetriolo.

Questo è solo per il login; prova a scrivere un test end-to-end in cetriolo!

I test dell'interfaccia utente dovrebbero coprire i percorsi degli utenti che sono tipicamente end-to-end ed esercitare più funzionalità di un'applicazione.

Ci sono molte cose che accadono in un viaggio di un singolo utente attraverso l'applicazione.

Il cetriolo NON è sicuramente lo strumento giusto per i test degli scenari utente / aziendale.