Sto facendo TDD errato quando più test possono fallire per lo stesso motivo?

6

Assumi un metodo con la seguente dichiarazione

public IList<Location> GetLocations() { ... }

Scrivo (almeno) i seguenti test

  1. Verifica se il metodo restituisce una raccolta vuota se non viene trovata alcuna posizione.
  2. Verifica se il metodo restituisce il numero corretto di posizioni.
  3. Verifica se i dati nelle posizioni restituiscono il metodo corretto.

Tuttavia, tutti i test precedenti falliranno se il metodo restituisce null. Mi sento come se un singolo errore dovesse comportare solo un errore di prova di un'unità, ma allo stesso tempo non vedo come evitarlo in uno scenario come questo. È così che funziona? a volte più test falliscono per lo stesso motivo?

    
posta user1323245 19.07.2014 - 18:21
fonte

2 risposte

16

La tua ipotesi è sbagliata,

I feel like a single error should only result in one unit test failure

ogni test unitario prova solo un aspetto del metodo, quindi:

  1. Verifica se il metodo restituisce una raccolta vuota se non viene trovata alcuna posizione.
  2. Verifica se il metodo restituisce il numero corretto di posizioni.
  3. Verifica se i dati nelle posizioni restituiscono il metodo corretto.

in ogni test precedente se il metodo restituisce null, test fallito è la risposta auspicabile

sometimes multiple tests will fail for the same reason?

L'unica risposta accettabile dovrebbe essere

    
risposta data 19.07.2014 - 18:41
fonte
2

Non sono d'accordo con la risposta di Infer-On. Infatti, anche se non sempre è realizzabile nella pratica, uno dovrebbe cercare di avere un singolo errore perché un solo test fallisce.

L'errore principale delle tue ipotesi è nel tuo elenco di comportamenti. Manca un test cruciale dall'elenco in base alle informazioni fornite:

0. Check to see if the method returns null when circumstance x occurs.

Questo è il test e solo in cui il metodo deve essere autorizzato a restituire null. Se restituisce null negli altri 3 test che hai elencato, quei test sono non che verificano ciò che rivendicano.

Per prima cosa, devi assicurarti che i tuoi comportamenti (test) stiano correttamente affermando ciò che vogliono. Roy Osherove in The Art of Unit Testing si occupa di questo dettaglio in abbondanza, ma per essere molto breve, sostiene un test il nome dovrebbe essere nella forma <method> <scenario> <behavior> . E, in effetti, il tuo primo test si attiene a questo, solo in un ordine leggermente diverso, che è perfettamente a posto (e il modo in cui tendo a farlo, come succede). Qui ho separato i componenti nel tuo nome test:

1. <method> <returns an empty collection> <if no locations are found>

Ma al tuo secondo e terzo test manca lo scenario.

2. <method> <returns the correct number of locations> <when what??>
3. <method> <returns correct location data> <when what??>

Diciamo che lo scenario (il "quando cosa ??") per entrambi (2) e (3) è qualcosa come "quando le coordinate sono date". (Sostituiscilo con qualsiasi adattamento nel tuo contesto.)

Tornando al punto principale, però, per tutti e 3 i test, se il metodo restituisce null allora è non data l'opportunità di cercare posizioni e non trovare nessuna (1) ed è non dati le coordinate corrette (2) e (3). Quindi quei test stanno fallendo ma per i motivi sbagliati.

Quindi da mettere in pratica: il test extra che ho introdotto sopra (0) gestisce il caso del metodo che restituisce null, quindi il metodo non deve restituire null nei restanti test. Devi strumentarli appropriatamente con i raddoppia dei test (tipicamente mock e / o stub) in modo da poter eliminare le influenze esterne e isolare con precisione cosa vuoi testare.

    
risposta data 22.07.2014 - 04:25
fonte

Leggi altre domande sui tag