Ogni metodo deve avere una classe di test JUnit separata?

11

Sto scrivendo i test dell'unità JUnit per le mie lezioni.

È meglio avere una classe separata per ogni metodo o avere solo una classe di test per ogni classe effettiva?

    
posta viraj 26.07.2014 - 09:29
fonte

5 risposte

14

Il modo in cui sono organizzati i test è piuttosto poco importante rispetto all'importanza di averli affatto.

La cosa più importante per una buona suite di test è che copre tutte le funzionalità; ciò garantisce che ogni volta che viene introdotto un difetto di regressione, si noterà immediatamente. Se scrivere un test per ciascun metodo, un test per ogni combinazione di valori di input di un metodo o anche un solo test per ogni possibile percorso di codice all'interno di quel metodo è meno importante. Se organizzare questi test in poche o molte classi di test è ancora meno importante: una suite di test dovrebbe sempre avere successo, quindi non importa se fallisce uno su tre o due su diciassette test - entrambi sono sbagliati e devono essere fisso.

Naturalmente, il codice di test è anche codice, quindi dovrebbe seguire le normali best practice per essere manutenibile, modulare, ecc. Ma ciò deve essere deciso in base alla capacità di manutenzione della suite di test stessa, non in base a come le classi di test riguardano le classi che testano. Entrambe le norme che menzioni possono aiutarti a ricordare dove trovare le cose se le segui in modo coerente, ma per questo la coerenza è più importante della scelta della politica.

    
risposta data 26.07.2014 - 09:36
fonte
4

Per la tua domanda specifica, la convenzione junit deve avere una corrispondenza 1-1 tra le classi dell'applicazione (Foo1.java, Foo2.java) e le classi di test junit (Foo1Test.java, Foo2Test.java) - link

Detto questo, sono d'accordo con tutto il cuore con l'evidenziazione di Kilian dell'importanza dello spirito / degli obiettivi del test unitario su qualsiasi schema organizzativo che potrebbe essere usato. Scegli alcune convenzioni e segui la maggior parte del tempo, mentre custodisci le eccezioni alle tue convenzioni quando sono garantite.

    
risposta data 26.07.2014 - 16:51
fonte
3

Is it better to have a separate class for each method, or have just one test class for every actual class?

Se hai la necessità di scrivere classi di test separate per metodi di una classe, allora hai la progettazione sbagliata. I metodi dovrebbero essere piccoli, facili da leggere, facili da testare e facili da modificare. I test potrebbero essere un po 'più lunghi, rispetto al codice originale dovuto alla creazione di testdata, derisione ecc. Ma non dovrebbero essere significativamente più lunghi. Se lo sono, la tua classe in prova è troppo complessa e sicuramente più di una cosa ( principio di responsabilità singola ). Lavora sul tuo design.

    
risposta data 26.07.2014 - 16:58
fonte
1

Penso sia giusto che ogni classe abbia la sua classe di test. L'idea è di centralizzare tutti i test unitari relativi alla classe target in una singola classe di test. Quindi, ad esempio, MyClass.java avrà la sua classe di test, MyClassTest.java.

    
risposta data 28.07.2014 - 07:05
fonte
1

Penso che sia "un test per metodo" sia "un test class per classe" siano in genere troppo estremi.

In generale si desidera avere un controllo per testmethod / unittest, questo potrebbe essere più asserzioni per esempio controllare che un list.isEmpty = true e list.Length = 0, quindi un testmethod / unittest per comportamento.
Ciò semplifica l'individuazione di un nome testmethod che descrive il comportamento. Vuoi raggruppare i metodi di test in una classe di test, quindi quando leggi il testclassname.testmethod ha senso. Di solito questi hanno un codice di configurazione condiviso che è quindi facile da inserire nella configurazione di test / dispositivo. A seconda della classe sottoposta a test, questa può essere una classe di prova per l'intera classe e può anche essere una classe di prova per un metodo. Ma di solito sarà nel mezzo.

Come per il codice normale, si desidera che i test siano leggibili il più possibile. Quello che mi aiuta è seguire lo stile BDD dato-quando-poi o organizzare-agire-assertare nell'organizzare il testcode. Un test può avere quel dato, la sua configurazione. Quindi ogni testmethod in quella classe usa quello dato (o parte di esso) e ne ha uno quando e uno poi.
Pensa anche alle unittests come documentazione su come usare le funzionalità della classe sotto test. Con una buona attivazione, puoi leggere i test per scoprire come utilizzare la funzionalità della classe che desideri utilizzare e quali saranno esattamente gli effetti.
Quando qualcosa si rompe e un unittest fallisce, vuoi che sia il più semplice possibile per capire cosa si è rotto, un'asserzione per test aiuta molto qui. Quando ci sono più affermazioni in un test, solo il primo fallisce e quindi il metodo termina, quindi non si sa se anche l'altro comportamento testato nei seguenti test viene interrotto fino a quando non si risolve il problema che ha fatto fallire la prima asserzione. Con una sola affermazione, tutti gli altri metodi di test vengono ancora eseguiti ed è molto più veloce per comprendere la profondità del fallimento.

Ovviamente sono d'accordo con Kilian Foth, in pratica puoi avere la fortuna di avere un paio di domande per il codice su cui stai lavorando. E qualsiasi piccolo test localizzato è meglio di nessun test, o solo grandi test di integrazione eseguiti sul build server, impiegano molto tempo e di solito non sono molto localizzati (non ti dicono velocemente dove si trova l'errore, sarai devo lavorarci un po ').

    
risposta data 23.03.2016 - 11:33
fonte

Leggi altre domande sui tag