Come posso testare un'unità di una GUI?


154

I calcoli nel mio codice sono ben testati, ma poiché c'è così tanto codice GUI, la mia copertura complessiva del codice è inferiore a quella che vorrei. Esistono linee guida sul codice della GUI per i test unitari? Ha senso?

Ad esempio, ci sono grafici nella mia app. Non sono stato in grado di capire come automatizzare il test dei grafici. Ci vuole un occhio umano, AFAIK, per verificare se il grafico è corretto.

(Sto usando Java Swing)


1
C'è un ottimo articolo sulle diverse architetture GUI di Martin Fowler ( martinfowler.com/eaaDev/uiArchs.html ). Descrive i compromessi dell'architettura della GUI in termini di unit test.
Roman Hwang,

1
Al giorno d'oggi, questa domanda sarebbe meglio fare su programmers.stackexchange.com (ed è probabilmente fuori tema su Stack Overflow, per il fatto di essere troppo ampia), ma le vecchie domande non possono essere migrate. La questione se appartenga qui a parte, il problema rimane interessante e difficile.
Mark Amery,

1
Sarebbe bello avere un esempio con un pezzo di codice della GUI e JUnit.
Witold Kaczurba,

1
Direi semplicemente rilassati e non preoccuparti. Gli sforzi compiuti nei test unitari non risultano sempre netti produttivi.
codeulike,

Vecchia domanda ancora, puoi testare il flusso nella GUI usando Jubula
Abi il

Risposte:


68

Disegni come MVP e MVC in genere cercano di estrarre quanta più logica possibile dalla GUI effettiva. Un articolo molto popolare su questo è "The Humble Dialog Box" di Michael Feathers. Personalmente ho avuto esperienze contrastanti con il tentativo di spostare la logica fuori dall'interfaccia utente - a volte ha funzionato molto bene, altre volte ha comportato più problemi di quanti ne valga la pena. È un po 'al di fuori della mia area di competenza.


??? "a volte ha funzionato molto bene, altre volte è stato più problematico di quanto valga la pena" Molto strano perché la maggior parte dei nuovi linguaggi tendono ad essere orientati a MVC ... che è una logica fuori dalla gui (Model-Visual) ...
Patrick Desjardins,

14
Tuttavia, la logica di presentazione sarà nella GUI. A volte, potrebbe essere tutt'altro che banale
Andrea


Il trattamento del concetto di Martin Fowler (nel caso in cui la tua rete, come la mia, filtri archive.org): martinfowler.com/eaaDev/uiArchs.html#HumbleView
Christopher Berman,

@ c24w grazie per aver tirato quello specchio, sei il vero MVP :)
John Baker,

38

Ovviamente, la risposta è usare MVC e spostare quanta più logica possibile dalla GUI.

Detto questo, molto tempo fa ho sentito da un collega che quando SGI stava eseguendo il porting di OpenGL su un nuovo hardware, avevano un sacco di test unitari che avrebbero disegnato una serie di primitive sullo schermo e poi calcolato una somma MD5 del frame buffer. Questo valore potrebbe quindi essere confrontato con valori hash noti noti per determinare rapidamente se l'API è accurata per pixel.


3
Mi piace questo approccio. Ingombrante da installare e mantenere, ma mi darebbe le capacità di test di regressione di cui ho bisogno.
Steve McLeod,

7
Danatel ti sei perso il punto. OpenGL è un'API per il rendering grafico con precisione dei pixel. I framework applicativi della GUI come Qt dipenderanno in larga misura dal chrome di sistema, quindi l'hashing del frame buffer non è un buon approccio.
Bob Somers,

1
Un MD5? Cosa c'entra un hash crittografico con questo? Come è coinvolta la sicurezza? Un hash, OK, è un'ottima idea per una grafica perfetta per i pixel ma un hash crittografico? È possibile utilizzare hash più veloci non crittografici e la cui probabilità di collisione è trascurabile. Sei sicuro che fosse un hash crittografico e non semplicemente un hash? (in aggiunta a ciò, in questi tempi e nell'era del calcolo parallelo, l'algoritmo di hashing [usato per scopi non crittografici] che non possono essere parallelizzati dovrebbe essere considerato con sospetto)
SyntaxT3rr0r

24
@ SyntaxT3rr0r: Quale funzione hash consiglieresti in questo tipo di applicazione non correlata alla sicurezza e quale livello di miglioramento delle prestazioni ci si potrebbe aspettare rispetto a MD5?
Lèse majesté,

1
Rispondere significa "non progettare mai la tua GUI e quindi non provarla". Freddo.
Dims

10

Puoi provare UISpec4J è una libreria Open Source funzionale e / o di test di unità per applicazioni Java basate su Swing ...


2
Ho iniziato a utilizzare UISpec4J da circa un mese per eseguire test di convalida dei requisiti sulla GUI di Java Swing. Finora mi è piaciuto molto.
Bassam,

github.com/UISpec4J/UISpec4J afferma che il tuo link è il sito ufficiale, ma non mi sembra ufficiale. Tutto quello che vedo è un blog sul
vlogging

7

C'è Selenium RC , che automatizzerà il test di un'interfaccia utente basata sul web. Registra le azioni e le riproduce. Dovrai comunque esaminare le interazioni con l'interfaccia utente, quindi questo non aiuterà con la copertura, ma può essere utilizzato per build automatizzate.


7

Puoi provare a usare Cucumber e Swinger per scrivere test di accettazione funzionale in inglese per le applicazioni della GUI di Swing. Swinger utilizza la libreria Jemmy di Netbeans sotto il cofano per guidare l'app.

Cetriolo ti permette di scrivere test come questo:

 Scenario: Dialog manipulation
    Given the frame "SwingSet" is visible
    When I click the menu "File/About"
    Then I should see the dialog "About Swing!"
    When I click the button "OK"
    Then I should not see the dialog "About Swing!"

Dai un'occhiata a questo video dimostrativo di Swinger per vederlo in azione.


6

Ecco alcuni consigli:

Prova a rimuovere la maggior parte del codice che puoi dalla GUI (con controller e oggetto modello) in questo modo sarai in grado di testarli senza la GUI.

Per l'immagine, è necessario testare il valore fornito al codice che genera l'immagine.


6

Il test è una forma d'arte. Sono d'accordo che la logica dovrebbe essere rimossa la GUI il più possibile. Possiamo quindi concentrare i nostri test unitari lì. Come qualsiasi altra cosa, i test riguardano la riduzione del rischio. Non è sempre necessario testare tutto, ma molte volte la cosa migliore è interrompere i diversi test in diverse aree.

L'altra domanda è cosa stai davvero cercando di testare a livello di interfaccia utente. Il test dell'interfaccia utente è il test più costoso perché di solito richiede più tempo per creare, mantenere ed è il più fragile. Se testate la logica per sapere che le coordinate sono corrette prima di provare a tracciare la linea, cosa state testando specificamente? Se si desidera testare un grafico con una linea rossa viene disegnato. Puoi dargli un set di coordinate predeterminate e testare se alcuni pixel sono rossi o non rossi? Come suggerito sopra i confronti di bitmap funzionano, Selenium ma il mio obiettivo principale non è quello di testare eccessivamente la GUI ma piuttosto testare la logica che aiuterà a creare l'interfaccia utente e quindi concentrarsi su quale parte dell'interfaccia utente si interrompe o è sospetta e focalizzare una manciata di test Là.


3

È possibile utilizzare JFCUnit per testare la GUI, ma la grafica può essere più impegnativa. In un paio di occasioni ho scattato istantanee della mia GUI e l'ho confrontata automaticamente con una versione precedente. Sebbene ciò non fornisca un test effettivo, ti avvisa se un build automatico non riesce a produrre l'output previsto.


3

Quello che raccolgo dalla tua domanda è che stai cercando un modo automatizzato per testare in dettaglio il tuo comportamento della GUI, l'esempio che dai è testare se una curva è effettivamente disegnata correttamente.

I framework di unit test forniscono un modo per eseguire test automatici, ma penso che il tipo di test che si desidera eseguire siano test di integrazione complicati che verificano il comportamento corretto di una moltitudine di classi, tra cui le classi del toolkit / libreria GUI, che l'utente non dovrebbe voler testare.

Le tue opzioni dipendono molto da quali piattaforme / toolkit / framework usi: ad esempio, un'applicazione che usa Qt come framework GUI può usare Squish per automatizzare i suoi test. Verifichi una volta i risultati dei tuoi test e i successivi test eseguiti automaticamente confrontano i risultati con i risultati verificati.



2

Il mio approccio ai test della GUI si sta evolvendo, così come il consenso del settore. Ma penso che alcune tecniche chiave stiano iniziando a emergere.

Uso una o più di queste tecniche, a seconda della situazione (ad es. Che tipo di GUI è, quanto velocemente deve essere costruita, chi sarà l'utente finale, ecc.).

  1. Test manuale. Hai sempre la GUI in esecuzione mentre lavori sul codice e assicurati che sia sincronizzata con il codice. È possibile testare e testare nuovamente manualmente la parte su cui si lavora mentre ci si lavora, passando dal codice all'applicazione in esecuzione. Ogni volta che completi un lavoro significativo, esegui un test generale dell'intero schermo o dell'area dell'applicazione, per assicurarti che non vi siano regressioni.

  2. Test unitari. Scrivi test per funzioni o piccole unità di comportamento della GUI. Ad esempio, i tuoi grafici potrebbero dover calcolare diverse sfumature di un colore in base a un colore "base". È possibile estrarre questo calcolo in una funzione e scrivere un test unitario per essa. È possibile cercare una logica come questa nella GUI (in particolare la logica riutilizzabile) ed estrarla in funzioni discrete, che possono essere più facilmente testate dall'unità. Anche comportamenti complessi possono essere estratti e testati in questo modo - ad esempio, una sequenza di passaggi in una procedura guidata può essere estratta in una funzione e un test di unità può verificare che, dato un input, venga restituito il passaggio corretto.

  3. Esplora componenti. Si crea una schermata 'explorer' il cui unico ruolo è mostrare tutti i componenti riutilizzabili che compongono la GUI. Questa schermata offre un modo rapido e semplice per verificare visivamente che ogni componente abbia l'aspetto e la sensazione corretti. Il componente explorer è più efficiente che passare manualmente attraverso l'intera applicazione, perché A) devi verificare ogni componente una sola volta, e B) non devi navigare in profondità nell'applicazione per vedere il componente, puoi semplicemente visualizzare e verificalo immediatamente.

  4. Test di automazione. Scrivi un test che interagisce con lo schermo o il componente, simulando clic del mouse, immissione di dati, ecc., Affermando che l'applicazione funziona correttamente date queste manipolazioni. Questo può essere utile come test di backup aggiuntivo, per acquisire potenziali bug che altri test potrebbero perdere. Tendo a riservare i test di automazione per le parti della GUI che sono più soggette a rotture e / o altamente critiche. Parti in cui voglio sapere il più presto possibile se qualcosa si è rotto. Ciò potrebbe includere componenti interattivi altamente complessi che sono vulnerabili alla rottura o importanti schermate principali.

  5. Test diff / snapshot. Scrivi un test che acquisisce semplicemente l'output come screenshot o come codice HTML e lo confronta con l'output precedente. In questo modo, sarai avvisato ogni volta che l'output cambia. I test diff possono essere utili se l'aspetto visivo della tua GUI è complesso e / o soggetto a modifiche, nel qual caso desideri un feedback rapido e visivo sull'impatto che una determinata modifica ha sulla GUI nel suo insieme.

Piuttosto che usare pesantemente ogni possibile tipo di test, preferisco scegliere la tecnica di test in base al tipo di cosa su cui sto lavorando. Quindi in un caso estrarrò una funzione semplice e la proverò in unità, ma in un altro caso aggiungerò un componente a Esplora componenti, ecc. Dipende dalla situazione.

Non ho trovato che la copertura del codice sia una metrica molto utile, ma altri potrebbero averne trovato un uso.

Penso che la prima misura sia il numero e la gravità dei bug. La tua prima priorità è probabilmente avere un'applicazione che funzioni correttamente. Se l'applicazione funziona correttamente, dovrebbero esserci pochi o nessun bug. Se ci sono molti o gravi bug, allora presumibilmente, non stai testando o i tuoi test non sono efficaci.

Oltre a ridurre i bug, esistono altre misure come prestazioni, usabilità, accessibilità, manutenibilità, estensibilità, ecc. Queste differiranno, a seconda del tipo di applicazione che stai costruendo, dell'azienda, dell'utente finale, ecc.

Tutto questo si basa sulla mia esperienza personale e sulla mia ricerca, nonché su un ottimo articolo sui test dell'interfaccia utente di Ham Vocke .


1

Da quello che so, questo è piuttosto complicato e dipende molto dalla lingua: numerose lingue hanno il loro modo di testare la GUI, ma se hai davvero bisogno di testare la GUI (al contrario dell'interazione modello / gui), spesso devi simulare un utente facendo clic sui pulsanti. Ad esempio, il framework SWT utilizzato in Eclipse fornisce SWTBot , JFCUnit è già stato menzionato, Mozilla ha il suo modo di simularlo in XUL (e da quanto ho letto sui loro blog, questi test sembrano essere piuttosto fragili).

A volte devi fare uno screenshot e testare il rendering perfetto per i pixel (credo che Mozilla lo faccia per verificare la corretta visualizzazione delle pagine) - questo richiede una configurazione più lunga, ma potrebbe essere quello che ti serve per i grafici. In questo modo, quando si aggiorna il codice e si interrompe un test, è necessario controllare manualmente l'immagine se l'errore è stato reale oppure è stato migliorato il codice di rendering del grafico per generare grafici più carini e è necessario aggiornare gli screenshot.


0

Se si utilizza Swing, FEST-Swing è utile per guidare la GUI e testare le asserzioni. È abbastanza semplice testare cose come "se faccio clic sul pulsante A, dovrebbe essere visualizzata la finestra di dialogo B" o "se seleziono l'opzione 2 dal menu a discesa, tutte le caselle di controllo dovrebbero essere deselezionate" .

Lo scenario grafico che hai citato non è così facile da testare. È abbastanza facile ottenere la copertura del codice per i componenti della GUI semplicemente creando e visualizzandoli (e magari guidandoli con FEST). Tuttavia, fare affermazioni significative è la parte difficile (e la copertura del codice senza asserzioni significative è un esercizio di autoinganno). Come si verifica che il grafico non sia stato disegnato capovolto o troppo piccolo?

Penso che devi solo accettare che alcuni aspetti delle GUI non possono essere testati efficacemente da test di unità automatizzati e che dovrai testarli in altri modi.


0

Non è compito tuo testare la libreria della GUI. Quindi puoi evitare la responsabilità di controllare ciò che è effettivamente disegnato sullo schermo e controllare invece le proprietà dei widget, fidandoti della libreria che rappresentano accuratamente ciò che viene disegnato.

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.