Domanda

In quali parti di un progetto scrivere unità di test è quasi o davvero impossibile? Accesso ai dati? ftp?

Se c'è una risposta a questa domanda, la copertura% 100 è un mito, non è vero?

È stato utile?

Soluzione

Qui ho trovato (tramite haacked qualcosa che Michael Feathers dice che può essere una risposta:

Dice

  

Un test non è un test unitario se:

     
    
        
  • Parla con il database
  •     
  • Comunica attraverso la rete
  •     
  • Tocca il file system
  •     
  • Non può essere eseguito contemporaneamente ad altri test unitari
  •     
  • Devi eseguire operazioni speciali nel tuo ambiente (come la modifica dei file di configurazione) per eseguirlo.
  •     
  

Sempre nello stesso articolo aggiunge:

  

Generalmente, i test unitari dovrebbero essere piccoli, testano un metodo o l'interazione di un paio di metodi. Quando si inserisce il database, i socket o l'accesso al file system nei test delle unità, questi non riguardano più questi metodi; riguardano l'integrazione del codice con quell'altro software.

Altri suggerimenti

Che una copertura del 100% sia un mito, per così dire, non significa che una copertura dell'80% sia inutile. L'obiettivo, ovviamente, è al 100%, e tra i test unitari e quindi i test di integrazione, puoi affrontarlo.

Ciò che è impossibile nel test unitario è prevedere tutte le cose totalmente strane i tuoi clienti faranno al prodotto. Una volta che inizi a scoprire queste sconvolgenti perversioni del tuo codice, assicurati di riportare i test per loro nella suite di test.

raggiungere una copertura del codice del 100% è quasi sempre dispendioso. Ci sono molte risorse su questo.

Nulla è impossibile per unit test ma ci sono sempre rendimenti decrescenti. Potrebbe non valerne la pena testare unità che sono dolorose per test unitari.

L'obiettivo non è la copertura del codice al 100%, né la copertura del codice all'80%. Un test unitario facile da scrivere non significa che dovresti scriverlo, e un test unitario difficile da scrivere non significa che dovresti evitare lo sforzo.

L'obiettivo di qualsiasi test è quello di rilevare i problemi visibili dell'utente nel modo più conveniente.

Il costo totale di creazione, manutenzione e diagnosi dei problemi contrassegnati dal test (compresi i falsi positivi) vale i problemi che il test specifico rileva?

Se il problema riscontrato dal test è "costoso", puoi permetterti di impegnarti per capire come testarlo e mantenerlo. Se il problema che il test rileva è banale, allora scrivere (e mantenere!) Il test (anche in presenza di modifiche al codice) è meglio che sia banale.

L'obiettivo principale di un test unitario è proteggere gli sviluppatori dagli errori di implementazione. Questo da solo dovrebbe indicare che troppi sforzi saranno uno spreco. Dopo un certo punto ci sono strategie migliori per ottenere una corretta implementazione. Inoltre dopo un certo punto i problemi visibili dell'utente sono dovuti all'implementazione corretta della cosa sbagliata che può essere colta solo dal livello utente o dai test di integrazione.

Cosa non testeresti? Tutto ciò che non potrebbe essere rotto.

Quando si tratta di copertura del codice, si desidera puntare al 100% del codice effettivamente scritto, ovvero non è necessario testare il codice della libreria di terze parti o il codice del sistema operativo poiché tale codice sarà stato consegnato testato. A meno che non lo sia. Nel qual caso potresti voler testarlo. Oppure, se sono presenti bug noti, nel qual caso potresti voler verificare la presenza dei bug, in modo da ricevere una notifica di quando sono stati corretti.

Anche il test unitario di una GUI è difficile, sebbene non impossibile, immagino.

L'accesso ai dati è possibile perché è possibile impostare un database di prova.

Generalmente le cose "non verificabili" sono FTP, e-mail e così via. Tuttavia, si tratta generalmente di classi quadro su cui puoi fare affidamento e quindi non è necessario testarle se le nascondi dietro un'astrazione.

Inoltre, la copertura del codice al 100% non è sufficiente da sola.

@GarryShutler

In realtà ho unittest e-mail utilizzando un server SMTP falso (Wiser). Verifica che il codice dell'applicazione sia corretto:

http: // maas-frensch.com/peter/2007/08/29/unittesting-e-mail-sending-using-spring/

Qualcosa del genere potrebbe probabilmente essere fatto per altri server. Altrimenti dovresti essere in grado di deridere l'API ...

A proposito: la copertura del 100% è solo l'inizio ... significa solo che tutto il codice ha effettivamente eseguito una volta .... niente sui casi limite ecc.

La maggior parte dei test, che richiedono configurazioni enormi e costose (in termini di costi delle risorse o di calcolo) sono test di integrazione. I test unitari dovrebbero (in teoria) testare solo piccole unità del codice. Funzioni individuali.

Ad esempio, se stai testando la funzionalità e-mail, ha senso creare un mock-mailer. Lo scopo di tale simulazione è assicurarsi che il codice chiami correttamente il mailer. Per verificare se l'applicazione invia effettivamente posta è un test di integrazione.

È molto utile fare una distinzione tra unit test e test di integrazione. I test unitari dovrebbero essere eseguiti molto velocemente. Dovrebbe essere facilmente possibile eseguire tutti i test unitari prima di controllare il codice.

Tuttavia, se la suite di test è composta da numerosi test di integrazione (che configurano e riducono database e simili), l'esecuzione del test può facilmente superare mezz'ora. In tal caso è molto probabile che uno sviluppatore non eseguirà tutti i test unitari prima di effettuare il check-in.

Quindi, per rispondere alla tua domanda: fai cose net unit test, che sono meglio implementate come test di integrazione (e non testare getter / setter - è una perdita di tempo ;-)).

Nel test unitario, non dovresti testare nulla che non appartiene alla tua unità; testare le unità nel loro contesto è una questione diversa. Questa è la risposta semplice.

La regola di base che uso è che dovresti testare l'unità qualsiasi cosa tocchi i confini della tua unità (di solito in classe, o qualunque altra sia la tua unità), e prendere in giro il resto. Non è necessario testare i risultati restituiti da alcune query del database, è sufficiente verificare che l'unità sputi la query corretta.

Questo non significa che non dovresti omettere cose difficili da testare; anche la gestione delle eccezioni e i problemi di concorrenza possono essere testati abbastanza bene usando gli strumenti giusti.

" Cosa non testare quando si tratta di unit test? " * Fagioli con solo getter e setter. Ragionamento: di solito è una perdita di tempo che potrebbe essere meglio impiegata a testare qualcos'altro.

Tutto ciò che non è completamente deterministico è un no-no per i test unitari. Volete che i vostri test unitari superino o falliscano SEMPRE con le stesse condizioni iniziali - se stranezze come il threading, la generazione casuale di dati, l'ora / le date o i servizi esterni possono influire su questo, allora non dovreste coprirlo nei test unitari . L'ora / le date sono un caso particolarmente brutto. Di solito puoi progettare il codice in modo che una data su cui lavorare sia iniettata (per codice e test) anziché fare affidamento sulla funzionalità alla data e ora correnti.

Detto questo, i test unitari non dovrebbero essere l'unico livello di test nella tua applicazione. Raggiungere il 100% di copertura dei test unitari è spesso una perdita di tempo e incontra rapidamente rendimenti decrescenti.

È molto meglio disporre di una serie di test funzionali di livello superiore e persino di test di integrazione per garantire che il sistema funzioni correttamente "una volta che tutto è unito" - che l'unità testa per definizione < strong> non testare .

Tutto ciò che richiede una configurazione molto grande e complicata. Naturalmente puoi testare ftp (client), ma poi devi configurare un server ftp. Per l'unità di prova è necessaria un'impostazione di prova riproducibile. Se non puoi fornirlo, non puoi testarlo.

Puoi testarli, ma non saranno test unitari. Il test unitario è qualcosa che non oltrepassa i confini, come attraversare il filo, colpire il database, eseguire / interagire con una terza parte, toccare una base di codice non testata / legacy ecc.

Qualunque cosa oltre a ciò è il test di integrazione.

La risposta ovvia alla domanda nel titolo è che non dovresti testare l'unità all'interno della tua API, non devi fare affidamento sul comportamento di qualcun altro, non dovresti testare nulla di cui non sei responsabile.

Il resto dovrebbe essere sufficiente solo per renderti in grado di scrivere il tuo codice al suo interno, non di più, non di meno.

Sicuramente la copertura del 100% è un buon obiettivo quando si lavora su un grande progetto, ma per la maggior parte dei progetti che correggono uno o due bug prima della distribuzione non vale necessariamente la pena di creare test unitari esaustivi.

Test approfonditi di cose come l'invio di moduli, l'accesso al database, l'accesso FTP, ecc. a un livello molto dettagliato sono spesso solo una perdita di tempo; a meno che il software in fase di scrittura non necessiti di un livello molto elevato di affidabilità (99,999% di roba), un test di unità eccessivo può essere eccessivo e un calo del tempo reale.

Non sono d'accordo con la risposta di quamrana riguardo al non testare codice di terze parti. Questo è l'uso ideale di un test unitario. Cosa succede se i bug vengono introdotti in una nuova versione di una libreria? Idealmente, quando viene rilasciata una nuova libreria di terze parti versione, si eseguono i test unitari che rappresentano il comportamento previsto di questa libreria per verificare che funzioni ancora come previsto.

La configurazione è un altro elemento che è molto difficile da testare bene nei test unitari. I test di integrazione e altri test devono essere eseguiti in base alla configurazione. Ciò riduce la ridondanza dei test e consente di liberare molto tempo. Cercare di configurare l'unità di test è spesso frivolo.

FTP, SMTP, I / O in generale dovrebbero essere testati usando un'interfaccia. L'interfaccia dovrebbe essere implementata da un adattatore (per il codice reale) e un mock per il test unitario.

Nessun test unitario dovrebbe esercitare la vera risorsa esterna (server FTP ecc.)

Se il codice per impostare lo stato richiesto per un unit test diventa significativamente più complesso del codice da testare, tendo a disegnare la linea e trovo un altro modo per testare la funzionalità. A quel punto devi chiedere come fai a sapere che il test unitario è giusto!

FTP, e-mail e così via puoi testare con un'emulazione del server. È difficile ma possibile.

Non sono verificabili alcuni errori di gestione. In ogni codice ci sono errori nella gestione che non possono mai verificarsi. Ad esempio in Java ci devono essere molte eccezioni perché fa parte di un'interfaccia. Ma l'istanza usata non la lancerà mai. O il caso predefinito di un interruttore se per tutti i casi possibili esiste un blocco del caso.

Naturalmente è possibile rimuovere parte della gestione degli errori non necessaria. Ma c'è un errore di codifica in futuro, allora questo è male.

Il motivo principale per cui si esegue il test unitario del codice è innanzitutto quello di convalidare il design del proprio codice. È possibile ottenere una copertura del codice del 100%, ma non senza usare oggetti finti o una qualche forma di isolamento o iniezione di dipendenza.

Ricorda, i test unitari non sono per gli utenti, ma per gli sviluppatori e la creazione di sistemi da utilizzare per convalidare un sistema prima del rilascio. A tal fine, i test unitari dovrebbero essere eseguiti molto rapidamente e avere il minor attrito di configurazione e dipendenza possibile. Prova a fare il più possibile in memoria ed evita di utilizzare le connessioni di rete dai test.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top