Un esempio di un caso di errore che avresti dovuto prefet catturare, è che l'oggetto in prova utilizza un livello di cache, ma non riesce a mantenere i dati come richiesto. Quindi, se interroghi l'oggetto, dirai "sì, ho il nuovo nome e indirizzo", ma vuoi che il test fallisca perché non ha effettivamente fatto quello che avrebbe dovuto.
In alternativa (e trascurando la violazione di responsabilità singola), supponiamo che sia necessario mantenere una versione con codifica UTF-8 della stringa in un campo orientato ai byte, ma in realtà persiste Shift JIS. Qualche altro componente leggerà il database e si aspetta di vedere UTF-8, quindi il requisito. Quindi il round-trip attraverso questo oggetto riporterà il nome e l'indirizzo corretti perché verrà convertito da Shift JIS, ma l'errore non viene rilevato dal test. Si spera che verrà rilevato da alcuni test di integrazione successivi, ma l'intero punto dei test unitari è quello di individuare i problemi in anticipo e sapere esattamente quale componente è responsabile.
If one of them is not doing what it's supposed to, then its own test case will fail and we can fix it and run the test battery again.
Non puoi supporre questo, perché se non stai attento scrivi una serie di test reciprocamente dipendenti. Il "salva?" test chiama il metodo di salvataggio che sta testando e quindi il metodo di caricamento per confermarlo. Il "carica?" test chiama il metodo di salvataggio per configurare il dispositivo di prova e quindi il metodo di caricamento che sta testando per verificare il risultato. Entrambi i test si basano sulla correttezza del metodo che non stanno testando, il che significa che nessuno dei due test effettivamente la correttezza del metodo che sta testando.
L'indizio che c'è un problema qui è che due test che presumibilmente stanno testando unità differenti in realtà fanno la stessa cosa . Entrambi chiamano un setter seguito da un getter, quindi controllano che il risultato sia il valore originale. Ma volevi testare che il setter persiste sui dati, non che la coppia setter / getter lavori insieme. Quindi sai che qualcosa non va, devi solo capire cosa e correggere i test.
Se il tuo codice è ben progettato per il test delle unità, allora ci sono almeno due modi per testare se i dati sono stati effettivamente mantenuti correttamente dal metodo sotto test:
-
prendi in giro l'interfaccia del database e prendi nota del fatto che sono state richiamate le funzioni appropriate, con i valori previsti. Questo verifica che il metodo faccia quello che dovrebbe, ed è il classico test unitario.
-
passa a un vero database con esattamente la stessa intenzione , per registrare se i dati sono stati persi o meno correttamente. Ma piuttosto che avere una funzione derisoria che dice semplicemente "sì, ho i dati giusti", il tuo test ritorna direttamente dal database e conferma che è corretto. Questo potrebbe non essere il test più puro , perché un intero motore di database è una cosa abbastanza grande da usare per scrivere un finto glorificato, con più possibilità di trascurare qualche sottigliezza che fa passare un test anche se qualcosa è sbagliato (quindi per esempio non dovrei usare la stessa connessione al database per leggere come è stato usato per scrivere, perché potrei vedere una transazione senza commit). Ma mette alla prova la cosa giusta, e almeno sai che precisamente implementa l'intera interfaccia del database senza dover scrivere alcun codice di simulazione!
Quindi è un semplice dettaglio dell'implementazione del test se leggo i dati dal database di test da JDBC o se sto prendendo in giro il database. In ogni caso, il punto è che posso testare l'unità isolandola meglio di me se permetto che possa cospirare con altri metodi errati sulla stessa classe per guardare bene anche quando qualcosa non va. Pertanto voglio utilizzare qualsiasi mezzo utile per verificare che i dati corretti siano persistenti, diversi da fidati del componente il cui metodo sto testando.
Se il tuo codice è non ben progettato per il test dell'unità, allora potresti non avere scelta, perché l'oggetto il cui metodo vuoi testare potrebbe non accettare il database come dipendenza iniettata. Nel qual caso la discussione sul modo migliore per isolare l'unità in prova, cambia in una discussione su quanto vicino è possibile arrivare ad isolare l'unità sotto test. La conclusione è la stessa, però. Se riesci a evitare cospirazioni tra unità difettose, lo fai, in base al tempo disponibile e a qualsiasi altra cosa tu pensi che sarebbe più efficace nel trovare errori nel codice.