Se dovessi avere una sola asserzione per test; come testare più ingressi?

15

Sto cercando di creare alcuni casi di test e ho letto che dovresti provare a limitare il numero di asserzioni per ogni caso di test.

Quindi la mia domanda è, qual è il modo migliore per testare una funzione con più input. Ad esempio, ho una funzione che analizza una stringa dall'utente e restituisce il numero di minuti. La stringa può essere nella forma "5w6h2d1m" , dove w, h, d, m corrisponde al numero di settimane, ore, giorni e minuti.

Se volessi seguire la regola "1 asserzione per test", dovrei effettuare più test per ogni variazione di input? Sembra sciocco quindi ho solo qualcosa tipo:

self.assertEqual(parse_date('5m'), 5)
self.assertEqual(parse_date('5h'), 300)
self.assertEqual(parse_date('5d') ,7200)
self.assertEqual(parse_date('1d4h20m'), 1700)

Nell'un caso di test. C'è un modo migliore?

    
posta speg 21.11.2012 - 14:17
fonte

4 risposte

23

Un modo più pragmatico per visualizzare la regola "assert per test", consiste nel far sì che le affermazioni in un singolo test coprano un singolo concetto.

In questo modo stai ancora testando un singolo concetto in un singolo test. Nel tuo caso, se la stringa di input è stata analizzata correttamente in una singola data.

Dovresti esercitare il tuo giudizio caso per caso per verificare se stai meglio testare un singolo concetto con più affermazioni o avere una singola affermazione in molti test.

Scegli l'opzione che consente test più chiari, meno ripetizioni pur avendo i tuoi test in grado di evidenziare diversi punti di errore nel tuo metodo. Vuoi che sia chiaro quando un test fallisce esattamente quello che è successo invece di dover eseguire il debug del test per scoprire cosa è andato storto.

    
risposta data 21.11.2012 - 14:58
fonte
17

Dipende molto dalla tua libreria di test. Nella libreria C # NUnit puoi fare qualcosa del tipo:

[TestCase('5m', 5)]
[TestCase('5h', 300)]
[TestCase('5d', 7200)]
[TestCase('1d4h20m', 1700)]
public void ParseDateTest(inputString, expectedMinutes)
{
    Assert.That(parse_date(inputString), Is.EqualTo(expectedMinutes));
}
    
risposta data 21.11.2012 - 15:21
fonte
3

Sì, esegui più test per ogni variazione di input.

L'obiettivo principale dell'unica asserzione per linea guida di test è di avere (idealmente) che un errore porti a un fallimento del test e viceversa in modo da sapere esattamente cosa è fallito. Quindi puoi lavorare con un test molto preciso per eseguire il debug della causa principale e verificare. Puoi rompere questo con un assert, e puoi stare bene con più affermazioni. In questo particolare scenario, avrei un test per ogni suffisso e alcune combinazioni di ordinamento.

Si spera che sia chiaro perché isolare i test è un vantaggio: si spreca meno tempo nel debugging quando qualcosa va storto. Ora, se sei veramente sicuro che il test sia improbabile, e che il sovraccarico della caccia attraverso il test è piccolo, allora forse ha senso testarli tutti in una volta per risparmiare tempo di implementazione .

Ma la storia ha dimostrato che risparmiare un po 'di tempo per scrivere codice a scapito della lettura / utilizzo del codice è mai che vale la pena. Da qui la linea guida.

    
risposta data 21.11.2012 - 14:48
fonte
1

I puristi direbbero che le asserzioni per diversi valori di input dovrebbero essere inserite in metodi di test separati all'interno della classe di test. Una ragione di ciò è che, a seconda dell'interfaccia utente di test, è spesso più facile distinguere tra i singoli errori di test che tra le singole asserzioni, il che potrebbe portare a identificare più rapidamente l'origine dell'errore.

Durante i test con JUnit possiamo aggirare questo usando la versione dei metodi assert * con un argomento String iniziale per differenziare un'asserzione da un'altra all'interno dello stesso metodo di test.

self.assertEqual("just minutes", parse_date('5m'), 5)
self.assertEqual("just hours", parse_date('5h'), 300)
self.assertEqual("just days", ('5d') ,7200)
self.assertEqual("days, hours, minutes", parse_date('1d4h20m'), 1700)
    
risposta data 21.11.2012 - 14:39
fonte

Leggi altre domande sui tag