Come si esegue il test dell'unità su un'interfaccia utente? [chiuso]

7

Uso JavaScript con JQuery per un'applicazione Rails. Ho un comportamento dinamico in questo. Come sviluppatore di Ruby, mi piace TDD / BDD, in particolare con RSpec. Per il momento, provo il mio JavaScript manualmente. Non è il modo migliore perché un cambiamento, da qualche parte, può infrangere il codice da qualche altra parte. Il è un sacco di avantages di usare TDD.

Il test in javascript sembra complicato perché dovrebbe testare molte interazioni con l'utente. Posso testare il comportamento in completa integrazione, ad esempio con Capybara, ma i miei test saranno molto lenti.

Ad esempio, ho un modulo con comportamento dinamico. In questo modulo, ho 5 o 6 campi dinamici che cambiano se seleziono un'opzione, scelgo un pulsante di opzione o spunta una casella di controllo. In alcuni casi, ci sono chiamate Ajax. Per questo modulo, penso di poter fare circa 20 test solo per un modulo. È davvero utile avere questo test?

Quindi, quali sono le tue regole per un'applicazione web standard?

    
posta Dougui 07.08.2013 - 18:50
fonte

3 risposte

12

Verifica solo se porta valore

Non eseguo test tipicamente, ma se lo facessi, certamente non punterei a nessun numero percentuale di copertura o test di caricamento di fronte a tutto ciò che ho scritto, ma mi concentrerei piuttosto sulla gestione di cose che non controllo e su cose che sono stati codificati male che non ho tempo di riscrivere.

Se il comportamento delle cose che controllo e che ho effettivamente scritto è imprevedibile, il mio problema non è che non ho test, è che ho scritto codice piss-poor che sarà sgraziato e una bestia da mantenere a prescindere da quanto presto scopro che sta agendo in su (che di solito è subito sul lato client se non hai permesso che fosse sopraffatto da complessità senza senso). Hai solo così tanto tempo e l'interfaccia utente tende a coinvolgere troppi fattori per tentare di microgestire il processo di scrittura con successo con qualcosa come un approccio TDD test-first. Preferisco concentrarmi sul mantenere il codice pulito, ovvio, minimo e robusto.

Bury the DOM

IMO, la chiave per scoprire cose che sono ragione per testare è seppellire tutte le cose sul lato client in oggetti che possono essere manipolati di più a livello di un'app a livello di architettura. L'obiettivo è che al più alto livello - in modo tipico codice di implementazione e riutilizzabile - hai solo oggetti di vaniglia. Non stai guardando i metodi ajax che vengono alimentati con grandi serie di opzioni e $ e document.getViaRidiculouslyExplicitlyNamedMethod , Stai guardando cose come comboFactory.build('combo_class_name') che qualsiasi dev del lato server che era per lo più incapace di capire il lato client poteva fuori come usare.

Ciò che fa per te è dividere le minuzie delle cose relative al DOM in cui mantenere le cose solide non è semplice come caricare i test di fronte a ogni piccola cosa che scrivi, dai più problemi di flusso di dati a livello di app che puoi effettivamente pensare in termini di un diagramma di flusso. Ecco dove concentrerei gli sforzi di test se li volessi.

Quindi, nel caso del tuo pazzo modulo dinamico:

Se il tuo ajax è tutto impacchettato in oggetti di servizio o in parte di uno stupido strato di dati senza interruzioni che nasconde completamente il fattore di comunicazione asincrono, non è necessario testare nel contesto del modulo. Le chiamate di assistenza funzionano o no. Possono essere testati in modo indipendente.

Per gli input dei moduli dinamicamente popolati, la maggior parte di questi input viene caricata da un'altra cosa che viene impostata. Non prenderei in considerazione una cosa del genere che meriti di essere testata poiché è più probabile che si rompa a causa di shenanigans del DOM legati a CSS o HTML se i tuoi servizi già controllano. Quindi, forse al massimo il selenio. ma i test unitari non hanno davvero senso per me lì. Test-first-TDD non ha mai avuto senso per me, ma soprattutto non per qualcosa del genere.

Architettura riflessiva prima

Se abbiamo una forma ultra-complicata con input che si popolano e mutano in base a tutti gli altri 20 stati di input in quella forma, supponendo che non avessi il potere di richiedere una riprogettazione (che in genere sarebbe il vero problema in quel caso) , Andrei con un approccio basato sugli eventi legato ai dati in modo tale che ogni manipolazione di input alterasse un insieme di dati, attivando eventi sull'oggetto dati stesso che potrebbero causare la modifica di altre parti del modello di dati, ma gli input stessi al massimo impostano il parte dei dati di cui si preoccupano e ascoltano le modifiche a quel set di dati che determinano al massimo una manciata di diversi tipi di comportamento.

Per ogni input, ci sono due semplici strade con branching minimo che funzionano o non funzionano e non è probabile che cambino in un modo in cui i potenziali fail-point non sono ovvi ed è facile testare a fondo prima di commettere . Ciò mantiene la ragnatela di relazioni limitata a qualunque sia l'astrazione dei dati, restringendo tutte le cose più incerte fino a qualcosa che a lui interessa solo ciò che rimane quando vengono alterati altri elementi di dati.

La domanda è ciò che apprezzi di più, ciò che ho appena descritto o qualcosa di un po 'più intricato e confuso, ma con prove dappertutto. La mia opinione è abbastanza strongmente ponderata sulla prima, ma se riesci a gestire entrambi, potere a te.

Nell'interfaccia utente, il principio DRY è fondamentale, IMO. Non aggiungere test a meno che non ci sia una buona argomentazione sul fatto che aggiungeranno valore per un tempo maggiore dedicato alla creazione di una base di codici, in modo tale che sia facile da leggere, facile da modificare e facile da riutilizzare in altre parti. Tutte e tre queste cose richiedono una serie di altre euristiche critiche ampiamente riconosciute nel mestiere di codifica per le quali non c'è alcun sostituto nella mia esperienza. Questi sono i fattori che guidano la mia architettura e, di conseguenza, non è difficile aggiungere test la maggior parte delle volte, se lo voglio, ma non permetterei mai che una strategia di testing guidi effettivamente la mia architettura. Sto solo iniziando a diventare più un generalista ma sono abbastanza convinto a questo punto che queste priorità funzionino bene per qualcosa di più della semplice interfaccia utente web.

    
risposta data 08.08.2013 - 01:49
fonte
0

Al lavoro abbiamo appena iniziato a utilizzare jasmine per testare il nostro javascript. C'è un po 'di una curva di apprendimento (ma se hai familiarità con RSpec non sarà troppo male) e potrebbe richiedere un po' di cambiamento nel modo in cui strutturi il tuo codice, ma nel complesso è stata un'esperienza davvero positiva.

Tieni presente che si tratta di test di comportamento per il tuo codice. Questo non è un sostituto per i test di accettazione e integrazione.

    
risposta data 08.08.2013 - 00:09
fonte
0

Molte persone che conosco provengono dalla mentalità del test che si verifica da una persona, non da un test codificato. Questa è, naturalmente, la mancanza di una corretta comprensione di TDD usando strumenti come QUnit (uno dei miei preferiti). Ho usato QUnit per un framework di gioco JavaScript per garantire che i miei componenti abbiano svolto il lavoro.

Dipende da quanto sia complesso il tuo JS, come è stato progettato il JS (il test dell'unità richiede che sia sviluppato in modo modulare). Se è direttamente legato al DOM, sarà più difficile, ma non impossibile, da testare. Se stai solo testando alcuni compiti, non mi preoccuperei di per sé; tuttavia, se gran parte dell'interfaccia utente è basata su javascript, prenderei in considerazione l'utilizzo di un framework e la modularizzazione del codice laddove possibile.

    
risposta data 08.08.2013 - 03:04
fonte

Leggi altre domande sui tag