Quanti test per metodo?
Bene, il massimo teorico e altamente impraticabile è la complessità del N-Path (supponiamo che i test coprano tutti modi diversi attraverso il codice;)). Il minimo è UNO !. In base al metodo pubblico , cioè, non verifica i dettagli dell'implementazione, ma solo comportamenti esterni di una classe (restituisce valori e chiama altri oggetti).
Citi:
* E l'idea di testare ciascuno dei tuoi metodi con il proprio metodo di prova (in una relazione 1-1) sarà ridicola. *
e poi chiedi:
Quindi, se la creazione di un test per ciascun metodo è "ridicola", come / quando hai scelto ciò per cui scrivi i test?
Ma penso che tu abbia frainteso l'autore qui:
L'idea di avere one test method
per one method in the class to test
è ciò che l'autore chiama "risibile".
(Almeno per me) Non si tratta di "meno", si tratta di "più"
Quindi lasciami riformulare come l'ho capito:
E l'idea di testare ciascuno dei tuoi metodi con UN SOLO METODO (il suo metodo di prova in una relazione 1-1) sarà ridicola.
Per citare di nuovo il tuo preventivo:
Quando ti rendi conto che si tratta solo di specificare il comportamento e non di scrivere test, il tuo punto di vista cambia.
Quando pratichi TDD non pensi :
Ho un metodo calculateX($a, $b);
e ha bisogno di un test testCalculcateX
che testa TUTTO sul metodo.
Quello che TDD ti dice è pensare a come il tuo codice DOVREBBE FARE :
Ho bisogno di calcolare il più grande dei due valori ( primo caso di test! ) Ma se $ a è inferiore a zero, allora dovrebbe produrre un errore ( secondo caso di test! ) E se $ b è inferiore a zero dovrebbe .... ( terzo caso di test! ) e così via.
Vuoi testare comportamenti, non solo singoli metodi senza contesto.
In questo modo ottieni una suite di test che è documentazione per il tuo codice e VERAMENTE spiega cosa dovrebbe fare, forse anche perché :)
Come fai a decidere quale parte del tuo codice crei unit test?
Bene, tutto ciò che finisce nel repository o ovunque vicino alla produzione ha bisogno di un test. Non penso che l'autore delle tue citazioni non sarebbe d'accordo con quello che ho cercato di affermare in quanto sopra.
Se non si dispone di un test, diventa molto più difficile (più costoso) cambiare il codice, soprattutto se non si sta effettuando la modifica.
TDD è un modo per assicurarti di avere test per TUTTO ma finché SCRIVI i test va bene. Solitamente scriverli nello stesso giorno aiuta perché non lo farai più tardi, vero? :)
Risposta ai commenti:
una discreta quantità di metodi non può essere testata in un particolare contesto perché dipendono o dipendono da altri metodi
Bene, ci sono tre cose che quei metodi possono chiamare:
Metodi pubblici di altre classi
Possiamo deridere altre classi, quindi abbiamo definito lo stato lì. Abbiamo il controllo del contesto, quindi non è un problema.
* Metodi protetti o privati sullo stesso *
Tutto ciò che non fa parte dell'API pubblica di una classe non viene testato direttamente, di solito.
Volete testare il comportamento e non l'implementazione e se una classe fa tutto ciò che funziona in un unico grande metodo pubblico o in molti metodi protetti più piccoli che vengono chiamati è l' implementazione . Vuoi essere in grado di CAMBIARE quei metodi protetti SENZA toccare i tuoi test. Perché i tuoi test falliranno se il tuo codice cambia comportamento! Ecco a cosa servono i tuoi test, per dirti quando rompi qualcosa :)
Metodi pubblici sulla stessa classe
Non succede molto spesso? E se nell'esempio seguente piace, ci sono alcuni modi per gestirlo:
$stuff = new Stuff();
$stuff->setBla(12);
$stuff->setFoo(14);
$stuff->execute();
Che i setter esistano e non facciano parte della firma del metodo execute è un altro argomento;)
Ciò che possiamo testare qui è se l'esecuzione viene fatta esplodere quando impostiamo valori errati. Ciò setBla
genera un'eccezione quando si passa una stringa può essere testato separatamente, ma se vogliamo verificare che quei due valori consentiti (12 e 14) non funzionino INSIEME (per qualsiasi motivo) di quello è un caso di test.
Se vuoi una "buona" suite di test puoi, in php, forse (!) Aggiungere @covers Stuff::execute
un'annotazione per assicurarti di generare solo la copertura del codice per questo metodo e le altre cose che sono appena configurate devono essere testate separatamente (di nuovo, se lo vuoi).
Quindi il punto è: forse devi prima creare un po 'del mondo circostante, ma dovresti essere in grado di scrivere casi di test significativi che di solito abbracciano solo una o forse due funzioni reali (i setter non contano qui). Il resto può essere deriso dall'etere o essere testato prima e poi fatto affidamento (vedi @depends
)
* Nota: la domanda è stata migrata da SO e inizialmente riguardava PHP / PHPUnit, ecco perché il codice di esempio e i riferimenti provengono dal mondo php, penso che questo sia applicabile anche ad altre lingue poiché phpunit non differisce molto da altre xUnit framework di test.