Test di accettazione funzionale della GUI, rendendoli meno fragili / ostacolo allo sviluppo ulteriore

3

(Sfondo - passa all'istruzione in grassetto per il punto cruciale)

Sto lavorando al libro "Il software orientato agli oggetti in crescita, guidato dai test" di Freeman & Pryce, mentre lo sto applicando a un progetto che sto iniziando. La mia app è un'app Web in PHP che gestisce le interazioni eBay di un utente.

Sto usando Behat / Mink per scrivere i test end-to-end. Sono bloccato al primo test.

Nel libro, sottolineano l'importanza dei primi test di scrittura che poi guidano la scrittura del codice per farli passare. E che i test non dovrebbero ostacolare lo sviluppo, comprese le modifiche ai requisiti, il refactoring e così via.

Sottolineano che il primo test dovrebbe esercitare il sistema end-to-end; per esempio. comandare l'interfaccia utente, utilizzando un database, per interagire con un sistema esterno come eBay; e questa caratteristica dovrebbe essere minima.

Tuttavia, è improbabile che la GUI per il primo test rimanga tale per i test futuri, pertanto i primi (e successivi) test dovrebbero essere il più flessibili possibile in modo che le inevitabili modifiche alla GUI non si interrompano i test (che avrebbero almeno due effetti collaterali importanti: il tempo che riscrive i test, E rischiando che quei test riscritti non riescano a catturare i bug che gli originali avrebbero catturato). Quest'ultimo è ciò che mi preoccupa davvero - Nel libro "The Pragmatic Programmer" enfatizzano "Trova bug una volta ".

Quindi questo è il problema astratto. Applicandolo al mio progetto, stavo pensando di scrivere prima una porzione del sistema che accumula i record degli acquisti fatti dall'utente. Ciò comporterebbe la creazione di notifiche su eBay che effettuano una chiamata alla mia applicazione ogni volta che un cliente si impegna ad acquistare qualcosa dall'utente. Il test funzionale dovrebbe simularlo e quindi verificare tramite la GUI che l'ordine appare nella lista (che implementerei inizialmente come una semplice, unica tabella HTML) visibile all'utente.

Ma una volta che il cliente si impegna ad acquistare, deve quindi pagare tramite Paypal. I record che l'app gestisce diventano quindi complessi, poiché alcuni utenti potrebbero non pagare mai, alcuni pagheranno, alcuni avranno rimborsi completi, rimborsi parziali, più rimborsi, i messaggi potrebbero essere scambiati tra l'utente e il cliente, l'utente potrebbe voler stampa etichette postali dall'interfaccia, ecc. ecc.

Quindi, in tutta probabilità, la GUI diventerà irriconoscibile da quella scritta per soddisfare la prima funzione di test.

In che modo è possibile gestire meglio questi due problemi?

  1. Tempo necessario per l'adattamento del codice di test della GUI
  2. Rischio di vecchi test riscritti che non riescono a rilevare bug per una vecchia funzionalità che i test precedenti avrebbero rilevato

Ho trovato alcune idee, ma mi sembra una scatola di pandora che mi ha sopraffatto, e mi chiedo se qualcuno possa indicarmi la giusta direzione, possibilmente con riferimento ad altri libri ecc.

  1. Prima idea: scrivi i test Behat (Gherkin) che rimarrebbero invariati, ma modifica il codice Mink che interpreta tali dichiarazioni ogni volta che la GUI viene modificata. Questo risolve pochissimi problemi, ma almeno le dichiarazioni Gherkin probabilmente non necessitano di modifiche.
  2. (Idea estremamente vaga) Rendi il layer della GUI il più sottile possibile, possibilmente strati multipli di astrazioni di wafer solo per la GUI, con le astrazioni corrispondenti nei test, un po 'come in modo tale da evitare cambiamenti nella GUI da influenzare gran parte dei test. (Onestamente, non ho idea di come funzionerebbe).
  3. Freeman / Pryce danno un suggerimento: "Apporta le modifiche nel più piccolo passo possibile". Ciò semplifica la correlazione delle modifiche nei requisiti / progettazione della GUI con le modifiche nei test. Ma alla fine, mentre i cambiamenti nella GUI si accumulano, non vedo come anche il rischio di test inefficaci non si accumulerebbe.

Chiedo scusa per la lunga domanda.

    
posta CL22 03.08.2015 - 15:29
fonte

1 risposta

3

Non scrivere test GUI per abbinare la GUI. Scrivi test di accettazione che soddisfano i requisiti

Potresti scrivere i tuoi test in questo modo:

  • Dato inserisco "utente" nel campo username e "pass" nel campo password
  • E faccio clic sul pulsante "Accedi"
  • Quando faccio clic sul pulsante Trova utente
  • E inserisco "foo" nel campo nome utente
  • E faccio clic su "Cerca"
  • Quindi dovrei vedere un tavolo con un utente "Johnny Foo" nella riga "1"
  • E dovrei vedere un tavolo con un utente "Manny Foo" nella riga "2"

Oppure potresti scriverli in questo modo:

  • Dato che sono registrato come "utente" con password "pass"
  • E cerco utenti chiamati "pippo"
  • Quindi i risultati della ricerca dovrebbero mostrare "Johnny Foo" sulla riga "1"
  • E i risultati di ricerca dovrebbero mostrare "Manny Foo" sulla riga "2"

Il primo ti accoppia completamente alla GUI. Il secondo ti accoppia solo a ciò di cui hai bisogno in termini di funzionalità, storie e requisiti.

In questo modo, si scrive codice che diventa riutilizzabile. Le linee nei tuoi test sono espressioni funzionali e c'è un codice che corrisponde a queste all'implementazione della GUI concreta, ma se qualcosa cambia nella tua GUI devi solo fare un cambiamento in una posizione, che è il luogo dove si mappano cose come " Cerco utenti chiamati "pippo" "con codice GUI concreto.

Case-in-point: ieri ho cambiato pagina per un'applicazione su cui lavoro caricando un invio per recuperare e visualizzare i dati usando JSON e Knockout. Ciò significa che, invece di fare clic su un pulsante e attendere un invio, stavo ora visualizzando un'animazione di caricamento che va via quando i dati vengono caricati. Prova questo con l'esempio sopra: nel primo esempio dovrai aggiungere che aspetti come un passo, nel secondo ti limiti a taggare insieme a "Ricerco utenti chiamati 'pippo'" - implementazione. Ora se hai tre test che assomigliano al mio primo esempio, non c'è sudore. Ma cosa succede se ne hai dieci? O cento?

A proposito, se guardi gli esempi per Behat / Mink e il Gherkin DSL utilizza , vedrai che sono esempi molto generali e leggibili. Questo non è un caso, è un ottimo esempio di come dovresti pensare quando scrivi dei test a questo livello.

    
risposta data 03.08.2015 - 16:08
fonte

Leggi altre domande sui tag