2009-03-04 10 views
8

Sto pensando al caso in cui il programma non calcola davvero nulla, ma fa molto. Il test unitario ha senso per me quando scrivi delle funzioni che calcolano qualcosa e devi controllare il risultato, ma cosa succede se non stai calcolando nulla? Ad esempio, un programma che mantengo sul lavoro si basa sul fatto che l'utente compila un modulo, quindi apre un programma esterno e automatizza il programma esterno per fare qualcosa in base all'input dell'utente. Il processo è abbastanza coinvolto. Esistono 3000 righe di codice (distribuite su più funzioni *), ma non riesco a pensare a una singola cosa che abbia senso testare l'unità.Come funziona il test delle unità quando il programma non si presta a uno stile funzionale?

Questo è solo un esempio. Dovresti provare anche a testare i programmi "procedurali"?

* EDIT

+0

domanda eccellente. Ho anche trovato impossibile (anche se concesso sono un noob quando si tratta di test di unità) per testare applicazioni grafiche pesanti. Ad esempio, in che modo testare un'unità su un'app che consente all'utente di disegnare un poligono su un'immagine? Oltre ad avere un tester, siediti lì e prova. –

risposta

2

Sulla base della sua descrizione questi sono i luoghi Vorrei guardare a prova di unità:

  • Fa il lavoro di convalida forma di lavoro input dell'utente in modo corretto
  • Dato input valido dalla forma è il programma esterno chiamato correttamente
  • avanzamento in input dell'utente per il programma esterno e vedere se si ottiene l'uscita giusta

Dai suoni della descrizione il vero problema è che la il codice con cui stai lavorando non è modulare. Uno dei vantaggi che ho trovato con i test unitari è che il codice che è difficile da testare non è abbastanza modulare o ha un'interfaccia scomoda. Prova a suddividere il codice in parti più piccole e troverai i punti in cui ha senso scrivere test unitari.

0

Si dovrebbe almeno refactoring fuori la roba che sembra che potrebbe essere un problema e test di unità che. Ma di norma, una funzione non dovrebbe essere così lunga. Si potrebbe trovare qualcosa che è unità di prova degna volta che si avvia il refactoring

Good object mentor article on TDD

+0

Non intendevo implicare che il programma fosse una funzione. –

+0

ah, capisco. Bene, allora non vorresti testare una sorta di convalida dell'input dell'utente? Casi limite? Mancanza nulla? input di sanitizzazione? cose del genere ... –

+0

Immagino di non pensare che l'input sia abbastanza complicato da dover testare la sua validazione. Voglio dire, certamente il controllo nullo è abbastanza semplice da non aver bisogno di un test unitario per dirmi che ho fatto bene. –

2

Io non sono un esperto in questo, ma sono stato confuso per un po 'per la stessa ragione. In qualche modo le applicazioni che sto facendo non si adattano agli esempi forniti per il test UNIT (molto asincrono e casuale a seconda dell'interazione dell'utente pesante) Mi sono reso conto di recente (e per favore fammi sapere se ho torto) che non lo fa Ha senso fare una sorta di test globale ma piuttosto una miriade di piccoli test per ogni componente. Il modo più semplice è costruire il test nello stesso tempo o anche prima di creare le procedure effettive.

+0

"o anche prima di creare le procedure attuali." - TDD. – strager

1

Hai 3000 righe di codice in una singola procedura/metodo? Se è così, allora probabilmente dovrai refactoring il tuo codice in parti più piccole, più comprensibili per renderlo manutenibile. Quando lo fai, avrai quelle parti che puoi e dovresti testare unitamente. Se no, allora hai già quei pezzi - le singole procedure/metodi che sono chiamati dal tuo programma principale.

Anche senza test di unità, è comunque necessario scrivere test per il codice per assicurarsi di fornire gli ingressi corretti al programma esterno e testare che si gestiscano correttamente le uscite dal programma in condizioni normali ed eccezionali . Le tecniche utilizzate nei test delle unità, come il mocking, possono essere utilizzate in questi test di integrazione per garantire che il programma funzioni correttamente senza coinvolgere la risorsa esterna.

+0

Cosa succede se l'output è cartaceo? –

+0

È ancora possibile verificare con una simulazione se i parametri corretti sono passati al programma esterno in base agli input utente dati. Ogni funzione può essere testata per garantire che esegua l'azione corretta in base ai suoi input. È più difficile se le funzioni hanno effetti collaterali ma sono comunque in grado. – tvanfosson

+0

Inoltre, se il programma sta eseguendo l'output, è possibile astrarre il pezzo che esegue l'output in un flusso. È quindi possibile sostituire un flusso simulato (flusso di memoria) e verificarlo tramite il test dell'unità. Se il programma esterno viene stampato su carta e non si ottiene nulla, non è necessario testare. – tvanfosson

0

Non è necessario implementare test automatici che testano singoli metodi o componenti. È possibile implementare un test unitario automatico che simula un utente che interagisce con l'applicazione e verificare che l'applicazione risponda nel modo corretto.

Suppongo che stiate testando manualmente la vostra applicazione al momento, in tal caso pensate a come potreste automatizzarla e lavorare da lì. Con il passare del tempo dovresti essere in grado di suddividere i tuoi test in blocchi progressivamente più piccoli che testano sezioni di codice più piccole. Qualsiasi tipo di test automatizzato di solito è molto meglio di niente.

+0

Beh, questa è sicuramente un'idea, ma è al di fuori della portata della domanda. Posso vedere il valore di questo. Lo capisco. Non capisco come posso usare il test delle unità. –

0

La maggior parte dei programmi (indipendentemente dal paradigma linguistico) può essere suddivisa in unità atomiche che prendono input e forniscono output. Come hanno menzionato gli altri risponditori, esaminate il refactoring del programma e scomporlo in parti più piccole. Durante il test, concentrarsi meno sulla funzionalità end-to-end e altro sui singoli passaggi in cui i dati vengono elaborati.

Inoltre, un'unità non deve necessariamente essere una funzione individuale (anche se questo è spesso il caso). Un'unità è un segmento di funzionalità che può essere testato utilizzando input e output di misurazione.Ho visto questo quando si utilizza JUnit per testare le API Java. I singoli metodi potrebbero non fornire necessariamente la granularità di cui ho bisogno per il test, anche se una serie di chiamate al metodo lo faranno. Pertanto, la funzionalità che considero come "unità" è un po 'più grande di un singolo metodo.

+0

Come ho chiesto a qualcun altro ... e se l'output è cartaceo? –

+0

Se stai raccogliendo dati da un utente, stai ancora passando dati da un'estremità all'altra.Per lo meno, è possibile eseguire il test dell'unità per assicurarsi che la formattazione sia corretta e che i dati vengano modificati da un'estremità all'altra. – bedwyr

0

Come pochi hanno risposto prima, ci sono alcuni modi per testare ciò che hai delineato. Prima l'input del modulo può essere testato in pochi modi. Cosa succede se vengono immessi dati non validi, dati validi, ecc. Quindi ciascuna funzione può essere testata per verificare se le funzioni fornite con varie forme di dati corretti e non corretti reagiscono nel modo corretto. Successivamente è possibile prendere in giro l'applicazione che viene chiamata in modo che sia possibile assicurarsi che l'applicazione invii ed elabori correttamente i dati ai programmi esterni. Non per essere sicuro che il tuo programma tratti anche dati inattesi dal programma esterno.

Di solito, il modo in cui trovo il modo in cui voglio scrivere i test per un programma che sono stato assegnato a mantenere, è vedere cosa sto facendo manualmente per testare il programma. Quindi prova a capire come automatizzare il più possibile. Inoltre, non limitare gli strumenti di test solo al linguaggio di programmazione in cui stai scrivendo il codice.

1

Un interessante "punto di riferimento" per la tua applicazione è che dici "l'utente compila un modulo". Se vuoi testare, devi rifattorizzare il tuo codice per costruire una rappresentazione esplicita di quel modulo come una struttura di dati. Quindi è possibile iniziare a raccogliere moduli e verificare che il sistema risponda in modo appropriato a ciascun modulo.

È possibile che le azioni eseguite dal sistema non siano osservabili fino a quando qualcosa non colpisce il file system. Qui ci sono un paio di idee:

  • creare qualcosa come un repository git per lo stato iniziale del sistema di file, eseguire un modulo, e guardare l'output di git diff. È probabile che questo sarà più simile ai test di regressione che ai test unitari.

  • Creare un nuovo modulo il cui unico scopo è rendere visibili le azioni del programma. Questo può essere semplice come scrivere testo pertinente su un file di registro o complesso come preferisci. Se necessario, è possibile utilizzare la compilazione condizionale o il collegamento per assicurarsi che questo modulo esegua qualcosa solo quando il sistema è in prova. Questo è più vicino ai test unitari tradizionali poiché ora è possibile scrivere test che dicono dopo aver ricevuto il modulo A, il sistema deve eseguire la sequenza di azioni B. Ovviamente devi decidere quali azioni dovrebbero essere osservate per formare un test ragionevole.

ho il sospetto vi ritroverete a migrare verso qualcosa che assomiglia di più test di regressione di test di unità per sé. Questo non è necessariamente male. Non trascurare la copertura del codice!

(Un'osservazione parentesi finale: nei brutti vecchi tempi di applicazioni di console interattive, Don Libes ha creato uno strumento chiamato Expect, che è stato estremamente utile in che consente di script di un programma che ha interagito come un utente A mio parere abbiamo un disperato. Ho bisogno di qualcosa di simile per interagire con le pagine Web. Penso che pubblicherò una domanda al riguardo :-)

+0

Questa risposta aiuta. Non sono sicuro di essere ancora lì, ma aiuta. Grazie. –

0

Penso che un'ondata di test di paranoia si stia diffondendo :) È bello esaminare le cose per vedere se i test avrebbero senso, a volte la risposta sarà no.

L'unica cosa che vorrei testare è assicurarsi che l'input del modulo fasullo sia gestito correttamente. Io davvero non vedo dove altro un test automatizzato potrebbe aiutare. Penso che vorrai che il test sia non invasivo (cioè nessun record viene effettivamente salvato durante i test), in modo da escludere le altre poche possibilità.

0

Se non riesci a testare qualcosa come sai che funziona? Una chiave per la progettazione del software è che il codice dovrebbe essere testabile. Ciò potrebbe rendere più difficile la scrittura vera e propria del software, ma in seguito ripagherà più facilmente.

Problemi correlati