2010-05-04 27 views
6

La scorsa notte io ei miei colleghi abbiamo avuto un po 'di disaccordo sui test unitari nella nostra applicazione PHP/MySQL. La metà di noi sosteneva che quando si testava una funzione all'interno di una classe, bisognava prendere in giro qualsiasi cosa al di fuori di quella classe e dei suoi genitori. L'altra metà di noi ha sostenuto che non si deve prendere in giro tutto ciò che è una dipendenza diretta della classe.Test unitario: obiettivo fondamentale?

L'esempio specifico era il nostro meccanismo di registrazione, che si è verificato attraverso una classe di registrazione statica e abbiamo avuto un numero di chiamate di Logging :: log() in varie posizioni all'interno della nostra applicazione. La prima metà di noi ha affermato che il meccanismo di registrazione dovrebbe essere simulato (fittato) perché verrebbe testato nei test dell'unità di registrazione. La seconda metà di noi ha sostenuto che dovremmo includere la classe Logging originale nel nostro test unitario in modo che se apportiamo una modifica alla nostra interfaccia di registrazione, saremo in grado di vedere se crea problemi in altre parti dell'applicazione a causa di errori per aggiornare l'interfaccia di chiamata.

Quindi immagino che la domanda fondamentale sia: i test di unità servono a testare la funzionalità di una singola unità in un ambiente chiuso o mostrano le conseguenze delle modifiche a una singola unità in un ambiente più ampio? Se è uno di questi, come realizzi l'altro?

+0

+1 Questa è una grande domanda, perché espone qualcosa che penso che molte persone siano confuse riguardo ai test unitari. – Fenton

risposta

11

Tu ei tuoi colleghi siete incappati nella differenza tra test unitari e test di integrazione. Schernire tutto sarebbe stato fatto per il primo; non si farebbe derisione delle dipendenze per quest'ultimo.

Naturalmente, il punto in cui si disegna la linea per la granularità è anche un po 'soggettivo, ma con il livello di dettaglio migliore per i test unitari, non dovresti preoccuparti di nulla al di fuori dello specifico argomento di ogni test.

+2

A volte, quando decidi che qualcosa è testato e parte della * piattaforma *, è ok decidere di usarlo anche all'interno dei test unitari. Ad esempio, non si potrebbe simulare una libreria standard o forse non un framework di cui si ha fiducia per funzionare correttamente. Se ti puoi permettere una tale fiducia, potrebbe risparmiare qualche riga di codice. –

+0

Sì, molto vero - tipicamente il mocking è riservato ai componenti sviluppati come parte del tuo progetto, solo che non sono la cosa attualmente in fase di test. – Amber

+0

+1 - Accetta che i test delle unità siano eseguiti in modo isolato e coprano il 100% del tuo codice. I test di integrazione vengono eseguiti all'unisono e la copertura non deve essere così elevata: si verifica l'interazione piuttosto che la funzione. http://www.enhance-php.com/Content/About-Unit-Testing/ – Fenton

1

Le parole danno alcuni suggerimenti per quanto riguarda la risposta:

unità significa 1: si sta cercando di provare una cosa. È possibile simulare dipendenze come il framework di registrazione quando questo non è l'obiettivo principale dei test. Il modo in cui l'unità testata interagisce con le sue dipendenze è spesso parte del test case e il mocking rende tutto più semplice.

integrazione significa più di una cosa che si unisce: si sta tentando di combinare più di una cosa insieme con un test nel suo insieme. Il mocking ha un ruolo minore, ma può comunque essere utile per emulare i dipendenti che sarebbero difficili da configurare nello scenario di test.

Direi che l'argomento per non prendere in giro il sistema di registrazione nei test di unità, per vedere se le modifiche interrompono qualcosa è piuttosto debole. Se qualcosa è rotto nel sistema di registrazione, allora dovrebbe essere catturato da un test dell'unità guastato per il sistema di registrazione.

Mantenere i test di unità semplici, chiari e mirati è una buona regola. Yuu ha bisogno di questa base di semplicità quando si espande lo scopo dei test. I test di integrazione possono diventare rapidamente complessi, specialmente quando li si utilizza come sostituti dei test delle unità mancanti: è come "eseguire il test a distanza" e più ci si allontana da un componente, più è difficile eseguire test e diagnosticare guasti. Testare una dipendenza distante attraverso un test unitario è come una persona che cerca di azionare il telecomando TV dall'altra parte della stanza usando una canna da pesca.

5

Il test delle unità è come testare un singolo componente in un dispositivo elettronico.

Se si desidera testare un transistor singolo in un amplificatore per chitarra, non collegare una chitarra, alzare il volume e controllare i suoni emessi. Sarebbe stupido. Per controllare un transistor, collegare l'apparecchiatura ai conduttori di del transistor e misurare solo gli ingressi e le uscite.

Ad un certo punto si verifica tutto (la chitarra emette rumore, ecc.), Ma questa è una cosa diversa rispetto al test di un singolo transistor.

0

@David, vedo che l'unità di test per te sta facendo il lavoro che dovrebbe fare.

Stai riflettendo sul design del tuo software.

Dal modo in cui stai ponendo la tua domanda sull'ambiente chiuso contro l'ambiente aperto, mi porterebbe a credere che tu sia sul punto di dover rispondere alla domanda di test di unità basati sul comportamento basato sullo stato per il tuo codice.

Non esiste una regola hard fast per quando utilizzare un oggetto reale o una simulazione per il test dell'unità. SOLO PRINCIPI GUIDA! Il problema del test dell'unità con un oggetto reale Logging è che i test per questo oggetto non saranno solo nei test dell'unità per il registratore ma anche nei test delle unità per gli oggetti che utilizzano il registratore.

Quindi se si dispone di 20 oggetti che utilizzano il registratore e quando si modifica l'interfaccia del logger ci saranno almeno 21 test non riusciti. Questo può essere piuttosto il dolore durante il refactoring. Ma d'altra parte, se non si usa la classe logger nei test delle unità di 20 oggetti e si cambia l'interfaccia del logger, si ha solo un test fallito e altri 20 test unitari che diventano verdi, anche se falliscono nella produzione.

L'unica intuizione che posso veramente darti è che non hai le astrazioni giuste sul posto. Potresti voler cercare SOLID. Questi dovrebbero essere i principi guida .

Ricorda quando le domande si presentano come se lo chiedessi è il codice che ti dà un feedback. Ascolta quel feedback. Ti farà risparmiare un sacco di dolore dopo.