2010-03-12 6 views
38

qualcosa che non va con il controllo tante cose in questo test unit ?:Più affermazioni sono errate in un test unitario? Anche se concatenando?

ActualModel = ActualResult.AssertViewRendered()  // check 1 
          .ForView("Index")   // check 2 
          .WithViewData<List<Page>>(); // check 3 

CollectionAssert.AreEqual(Expected, ActualModel);  // check 4 

Gli obiettivi primari di questo test sono per verificare la vista a destra viene restituito (controllare 2) e contiene i dati giusti (assegno 4).

Guadagnerei qualcosa suddividendolo in più test? Sto facendo tutto bene, ma non ho intenzione di dividere le cose se non ha un valore pratico.

Sono abbastanza nuovo al collaudo di unità, quindi sii gentile.

+0

Alcuni più discussione sul tema: http: // StackOverflow. it/questions/831390/multiple-asserts-in-single-test e http://stackoverflow.com/questions/762512/unit-testing-question – Alconja

+0

Tutte le buone risposte (tutte con upvoted), grazie! –

+0

Vedere anche http://programmers.stackexchange.com/questions/7823/is-it-ok-to-have-multiple-asserts-in-a-single-unit-test# –

risposta

29

Come altri hanno sottolineato, è meglio attenersi ad una affermazione in ogni test per evitare di perdere informazioni - se la prima affermazione fallisce, non si sa se anche quelle successive falliranno. Devi risolvere il problema con meno informazioni, il che potrebbe (probabilmente sarà) più difficile.

Un riferimento molto buono è quello di Roy Osherove Art of Unit Testing - se vuoi iniziare bene con Unit Testing, potresti fare molto peggio di iniziare da qui.

+2

Ho trovato quel libro molto buono. Ha migliorato enormemente la qualità dei miei test unitari. E mentre la maggior parte dei libri sullo sviluppo del software sono molto spessi, questo libro contiene circa 270 pagine. Questo rende molto utile inserire l'elenco obbligatorio della tua squadra. E se sei di fretta, Roy ti consiglia di leggere solo il capitolo 7. – Steven

2

È consigliabile attenersi a una sola affermazione in ogni test per evitare Assertion Roulette.

Se è necessario configurare lo stesso scenario per testare più condizioni in base a premesse identiche, è meglio estrarre il codice di configurazione in un metodo di supporto condiviso e quindi scrivere diversi test che chiamano questo metodo di supporto.

Ciò garantisce che ogni test case verifica solo una cosa.

Come sempre, ci sono eccezioni a questa regola, ma dal momento che sei un nuovo di unit test, mi sento di raccomandare che si bastone con il un'affermazione per ogni unit test regola fino a quando non hanno imparato quando va bene a deviare .

+0

Questo ha senso. Grazie! –

8

Fintantoché ogni affermazione ha un messaggio di errore univoco e identificativo, dovresti essere bravo e evitare i problemi di Assertion Roulette perché non sarà difficile dire quale test ha fallito. Usa il senso comune.

+5

Il problema di avere più affermazioni non è quello di dire quale fallito - nella maggior parte dei casi si ottiene il numero di riga, se non altro. Il problema è che non si riesce a vedere se anche i test successivi fallirebbero, quindi si finisce con meno informazioni sul bug. In alcuni casi questo non è significativo - ma in alcuni (la maggior parte, secondo la mia esperienza, prima di apprendere questa lezione) lo è. – Bevan

+1

* è che non si riesce a vedere se anche i test successivi fallirebbero * ma ciò non è rilevante. Correggi uno Assert per volta.È anche sicuro assumere che se il primo Assert sta fallendo, anche il prossimo avrà esito negativo perché le condizioni precedenti non sono soddisfatte. Nei miei test sostituisco la maggior parte delle dichiarazioni "if" con un Assert. A parte quando un ramo è valido (che non è quasi mai il caso). –

+0

Non sono d'accordo. Se hai tre diversi test e li esegui tutti, sarai in grado di vedere quali affermazioni sono passate e quali no. Più informazioni hai quando cerchi di aggiustare qualcosa, meglio sarà. Puoi apportare modifiche più precise per correggere ciò che è rotto. –

11

Notando per i futuri lettori che questa domanda e il suo duplicato Is it bad practice to have more than one assertion in a unit test? hanno opinioni di maggioranza opposte, quindi leggerle entrambe e decidere per conto vostro.

La mia esperienza è che il quantum di test più utile non è l'asserzione, ma lo scenario - cioè, ci dovrebbe essere un test unitario per un dato insieme di condizioni iniziali e chiamata di metodo, con tante asserzioni quante sono necessario per affermare le condizioni finali previste. Avere un test unitario per asserzione porta a duplicare l'impostazione o soluzioni alternative tortuose per evitare la duplicazione (come i terribili contesti rspec profondamente nidificati che sto vedendo sempre di più ultimamente). Inoltre moltiplica i test, rallentando drasticamente la tua suite.

6

ho trovato un argomento diverso a questa domanda (almeno per me):

uso di più asserisce è OK se stanno testando la stessa cosa.

Per esempio, va bene fare:

Assert.IsNotNull(value); 
Assert.AreEqual(0, value.Count); 

Perché? - perché queste due affermazioni non nascondono l'intenzione del test. Se il primo asser fallisce, significa che anche il secondo fallirebbe. E in effetti, se rimuoviamo la prima affermazione, la seconda affermazione fallisce (con eccezione di riferimento null - !!!) quando lo value è nullo. Se così non fosse, non dovremmo mettere insieme queste due asserzioni.

Quindi, questo è sbagliato:

Assert.IsNotNull(value1); 
Assert.IsNotNull(value2); 

Come ho già detto in precedenza, se la prima asserzione fallisce, v'è una chiara indicazione circa la seconda asserzione - avremmo ancora voglia di sapere cosa succede al la seconda (anche se la prima non è riuscita). Quindi, per questa ragione, questi due asseriti appartengono a due diversi test unitari.

Conclusione: mettere uno o più afferma, quando fatto correttamente, diventa la questione della preferenza - se vogliamo vedere eccezioni affermazione nei risultati del test, o vogliamo vedere alcune altre eccezioni e, in particolare, casi.

0

So che questa è una domanda vecchia ma ho pensato di aggiungere il mio bit.

In genere, avrei avuto meno asserzioni possibili in ogni caso di test. I test possono essere spesso scritti per salvare molte affermazioni diverse.

Supponiamo di disporre di test di unità per un metodo che crea un saluto (ad esempio Mr Smith) dai componenti di un nome. Voglio verificare questo con un gran numero di scenari diversi, non è necessario avere un test separato per ciascuno.

Dato il seguente codice, ci sono molte diverse asserzioni. Quando falliscono, puoi risolverli uno alla volta fino a quando le asserzioni cessano.

Assert.AreEqual("Mr Smith", GetSalutation("Mr", "J", "Smith")); 
Assert.AreEqual("Mr Smith", GetSalutation("Mr", "John", "Smith")); 
Assert.AreEqual("Sir/Madam", GetSalutation("", "John", "Smith")); 
Assert.AreEqual("Sir/Madam", GetSalutation("", "J", "Smith")); 

Un'alternativa a questo è tenere un conteggio di problemi e affermarlo alla fine.

int errorCount = 0; 
string result; 

result = GetSalutation("Mr", "J", "Smith"); 
if (result == "Mr Smith") 
    errorCount++; 

result = GetSalutation("Mr", "John", "Smith"); 
if (result == "Mr Smith") 
    errorCount++; 

Assert.AreEqual(0, errorCount); 

In una situazione del mondo reale probabilmente mi piacerebbe aggiungere qualche traccia comandi di scrivere dettaglio dei singoli test che non hanno la finestra di output