Quanto deve essere grande il mio progetto per poterlo provare unitamente? [chiuso]


86

Presumo che il mio progetto sia abbastanza disaccoppiato da consentire il collaudo delle unità. Ma quanto grande, esattamente, in termini di clasi e funzioni deve essere il mio progetto per rendere utile il test unitario?

Tutti commettiamo errori e nessuno è perfetto, ma mi considero un programmatore decente per gestire gli errori di piccoli progetti con il passaggio. Oppure i test unitari sono una necessità ardua, indipendentemente dalle dimensioni del progetto?


26
Il grande presupposto errato che stai facendo è che il progetto è solo per te e che è solo per ora . E se lo lasci per qualche mese, fai qualcos'altro e poi torni ad esso? Avrai la stessa sicurezza di essere un "programmatore decente" (che non ha nulla a che fare con il test o meno)? E se qualcun altro prende il controllo del tuo progetto ...? Un grande blogger (purtroppo non più attivo) ha scritto che dovresti sempre "provvedere al lettore di codice, non allo scrittore di codice".
Amos M. Carpenter,

6
Che ne dici di questo (inteso per C # .NET): int x = 3 * (1/3); qual è il valore memorizzato in x dopo il completamento dell'operazione? Il mio punto è che anche un codice di riga potrebbe richiedere un test perché potrebbe portare a un bug, o perché non lo sai o perché lo sai ma hai fatto il codice sbagliato.
NoChance,

2
@aaamos, penso che ti sia sfuggito il punto. Il fatto che mi venga posta questa domanda da solo dimostra che prendo in considerazione anche la ristorazione per il lettore di codice.
Lamin Sanneh,

13
Avendolo fatto in entrambi i modi, posso dirti che è molto più facile scrivere i test mentre stai andando avanti (cioè mentre il progetto è piccolo) che tornare indietro e scrivere test unitari in seguito quando ritieni che il progetto abbia incontrato alcuni arbitrari " dovremmo scrivere i test ora "condizione.
Wonko the Sane,

1
Stai facendo la domanda sbagliata. Non importa quanto sia grande il progetto. La domanda è: quanto ti importa se è corretta? Se la correttezza è importante, i test unitari sono un modo efficace per migliorare la correttezza.
Mark E. Haase,

Risposte:


206

Il tuo progetto è già abbastanza grande.

Nella mia esperienza, una classe e una funzione sono state sufficienti per considerare la necessità di test unitari.

    class Simple {
        boolean reallySimple() {
            return true; // how do we make sure it doesn't change to false?
        }
    }


    class SimpleTest {
        void assertReallySimple() {
            // ensure reallySimple return value isn't changed unexpectedly
            UnitTestFramework.assertTrue(new Simple().reallySimple());
        }
    }

24
Sicuramente dovresti iniziare prima, al punto di funzione 0 class / 0 ... se stai seguendo TDD :)
Kaz Dragon

115
+1. Se il programma è abbastanza grande da contenere bug, è abbastanza grande da avere test unitari.
Jason Orendorff l'

9
@JasonOrendorff: lo sto prendendo in giro in un poster e lo metto nel mio ufficio. Brillante.
Justin ᚅᚔᚈᚄᚒᚔ

Inoltre consente un refactoring "sicuro".
Timo

7
Anche se non sono necessariamente in disaccordo con il sentimento, se il tuo codice è davvero così semplice potresti probabilmente scappare con solo affermazioni invece di test di unità completi.
Chuu,

109

Non ho mai accettato l'idea "devi provare tutto l'unità", anche se ci sono sicuramente persone là fuori che hanno (vedi la risposta di Gnat !).

Per quanto mi riguarda, i principali vantaggi dei test unitari sono:

  1. Aiutare a garantire che i cambiamenti non rompano le cose.
  2. Aiutarti a progettare interfacce sensibili per le tue classi (poiché ti costringe a essere un client per il tuo codice).
  3. Aiutare a documentare come dovrebbe essere usato il codice.

Fondamentalmente è necessario valutare il tempo necessario per scrivere e mantenere i test su questi fattori.

Il numero 1 è di solito sufficiente per valere la pena di scrivere test. Nella mia esperienza, prima o poi> 95% del codice viene modificato.


8
Concordi con questo: quando lavori in un singolo negozio di sviluppatori devi trovare un equilibrio tra la qualità del software e testare tutto (che può richiedere molto tempo). Non dimenticare che ogni volta che apporti una modifica, potresti dover modificare i test unitari per adattarli
Matt Wilko

1
Non dovresti testare tutto, ma dovresti testare qualsiasi comportamento esposto al mondo esterno. Ci sono / ci sono certamente costi di manutenzione per i test, e come Kent Beck ha detto in alcune risposte SO (penso che fosse SO) - test abbastanza per farti credere che il tuo codice sia corretto.
Wayne Werner,

10
Aggiungo che se si eseguono solo test automatici minimi, i test unitari hanno il livello sbagliato da raggiungere. Invece vai per test di integrazione / fumo di alto livello che spingono alcuni set di dati attraverso la tua app end to end senza deridere nulla. Volete che questi test esercitino il più possibile la vostra base di codice e coprano tutti i normali casi d'uso e percorsi di esecuzione. Una probabilità del 75% di sapere che le tue modifiche hanno rotto qualcosa, da qualche parte, nell'app è più vantaggiosa di una probabilità del 5% di sapere che hai rotto SomeClass.OneOfTheHandfulOfTestedFunctions ().
Dan Neely,

3
Penso che tu ne abbia perso uno: "Assicurati che il codice funzioni come dovrebbe!"
BlueRaja - Danny Pflughoeft

3
@ BlueRaja-DannyPflughoeft: In realtà, sarebbe più preciso dire: "Accertarsi che il codice superi i test unitari che hai scritto!"
Vaughandroid,

34

È semplice: non hai bisogno di test unitari se scarterai il programma dopo averlo eseguito una volta.

Se questo ti sembra eccessivo, considera cosa significherebbe l'alternativa. Se ci fossero delle dimensioni al di sotto delle quali i test unitari non pagano, dovresti continuare a giudicare nella tua mente: "Ho già raggiunto la dimensione magica? Dovrei iniziare a scrivere test?" Ora, i programmatori sono notoriamente cattivi nel predire il futuro e notoriamente cattivi nel giudicare la propria abilità. Il codice che ti appare cristallino ora diventerà incomprensibile, anche per te, anche aspettando un mese. Un progetto di cui sei assolutamente, assolutamente sicuro, non verrà mai più utilizzato e che ti aggiri semplicemente sulla remota possibilità che potresti voler cercare come hai risolto qualcosa in precedenza, verrà richiesto di nuovo e riceverai richieste di modifica.

È quindi molto probabile che tu giudichi erroneamente se i test sono utili o meno e quando inizi a necessitare di test, non sei già sicuro al 100% di quali siano esattamente la semantica esatta da testare. Poiché ritengo che tutti, tranne i banali programmi una tantum, traggano profitto dai test unitari, considero trascurabili i costi di uno sforzo prolungato nei test che non vengono mai più eseguiti a fronte dei rischi di estendere il codice non testato e compreso male.


22
I programmatori sono notoriamente cattivi nel giudicare la propria abilità di predire il futuro
superM

3
@superM Sono d'accordo con te. Il programma "corri una volta e butta via" che ho già scritto durante la mia breve carriera è rimasto tutto, è stato eseguito ogni pochi giorni ed è diventato critico per il business. Lo chiamo "temporarmanent", noto anche come effetto temporaneo-permanente .... sigh
Jalayn

@Jalayn La risposta non è semplicemente che si dovrebbe tornare indietro e aggiungere test unitari non appena questa realizzazione colpisce?
Cornel Masson,

@CornelMasson Hai perfettamente ragione, aspettati che spesso sia difficile convincere i manager che "non è ancora finito" perché mancano i test :-)
Jalayn

@Jalayn: troppo vero!
Cornel Masson,

22

Qualche tempo fa ho trovato un bel post: perché i test unitari accelerano lo sviluppo . Può aiutarti a rispondere alla domanda.

... E se al codebase ... fosse fornita una serie sostanziale di test unitari. Un set che direbbe: "se tutti i test hanno esito positivo, garantisco che il codice fa ancora quello che dovrebbe fare" e se un test fallisce ti mostra esattamente dove un comportamento è rotto. Questo è fantastico, potrei cambiare il codice per aggiungere le cose che voglio senza girovagare se il codice fa ancora quello che dovrebbe fare, ho appena eseguito i test ... e ho fiducia. Questo è un grande mondo come ingegnere del software. Ho notato che avrei potuto avanzare molto più velocemente ...

Io ho fede".

Questo è probabilmente il motivo più importante per cui i test unitari accelerano lo sviluppo in un contesto aziendale.

Posso fidarmi che tutto funziona ancora se tutti i test passano. Se i test falliscono, indicano esattamente dove si trova il problema ...

... devi avere una copertura di test unitaria elevata e buoni test unitari . Quando queste condizioni vengono rispettate ti ritroverai in una situazione in cui lo sforzo di aggiungere nuove funzionalità è quasi indipendente dalla dimensione dell'applicazione e che a lungo termine accelererà lo sviluppo .

Michael Feathers ha introdotto in uno dei suoi libri due modi di lavorare con le modifiche al codice:

  • modifica e prega,
  • coprire e modificare.

Non importa quanto sia grande la base di codice.


18

Secondo Kent Beck nella sua risposta alla domanda Stack Overflow Quanto sono profondi i test unitari? , dovresti testare il codice che tendi a sbagliare.

Se in genere non commetto un errore (come impostare le variabili sbagliate in un costruttore), non lo provo.


4
Un buon punto, e questo implica che la domanda del PO è sbagliata; se testare non ha nulla a che fare con le dimensioni del progetto. Una base di codice a 5 righe potrebbe richiedere dei test e un metodo a 1 riga in una base di codice di grandi dimensioni potrebbe non (sebbene altre cose in quella base di codice lo facciano).
Nathan Long,

Questo potrebbe funzionare per piccoli progetti su cui stai lavorando da solo, ma per un progetto che è fatto per lavoro (dove non controlli chi lo lavorerà in futuro) o per qualsiasi cosa che possa essere open source, è necessario per testare tutto. E devi iniziare immediatamente perché in seguito sarà "troppo difficile riempire tutto il codice già scritto"
xaxxon,

@xaxxon: Kent ne parla in realtà nella stessa risposta a cui Mansuro si è collegato, dicendo: "Quando scrivo un codice in una squadra, modifico la mia strategia per testare attentamente il codice che, collettivamente, tendiamo a sbagliare".
henko,

No, è ancora incredibilmente miope. Non puoi sapere chi lavorerà sul codice in futuro. Questo è il tipo di mentalità che affligge gli sviluppatori junior.
Xaxxon,

5

I test unitari sono implementati per risparmiare tempo e migliorare:

  • tracciamento dei bug
  • refactoring e / o riscrittura del codice
  • test d'integrazione
  • test di regressione, ecc.

È indispensabile scrivere unit test per parti del programma relativamente complesse.

Se sei sicuro che scrivere unità di test ora non ti farà risparmiare tempo in futuro, puoi saltarlo. Tuttavia, non lo sai mai, e personalmente non riesco a pensare a un caso in cui è più economico (in termini di tempo, denaro e nervi) non scrivere test unitari, ma invece eseguire tutti i test manualmente.


Generalmente una buona risposta, quindi +1. Tuttavia, penso che il tuo ultimo punto manchi del fatto che vorrai / dovrai ancora testare manualmente i tuoi test unitari!
vaughandroid

@Baqueta, forse non mi sembrava chiaro, ma non intendevo dire che i test unitari sostituiscono completamente i test manuali
superM

4

"Devo provare questo unit" di solito si può rispondere rispondendo alla seguente domanda: "È importante che questa funzione funzioni correttamente ed è importante per me sapere quando smette di funzionare?"

Certo, è molto più complicato di così, ma è un buon modo per iniziare. Alla fine peserai anche se il codice è già in fase di test in virtù dell'utilizzo in un'altra funzione o se il tuo tempo sarebbe meglio speso in un'altra funzione, ecc.


4

A meno che tu non scriva codice senza testarlo, dovrai sempre sostenere i costi del test.

La differenza tra avere unit test e non averli è la differenza tra il costo di scrivere il test e il costo di eseguirlo rispetto al costo del test a mano.

Se il costo per scrivere un test unitario è di 2 minuti e il costo per l'esecuzione del test unitario è praticamente pari a 0, ma il costo per testare manualmente il codice è di 1 minuto, si interrompe anche quando si è eseguito il test due volte.


Per molti anni ho avuto il malinteso di non avere abbastanza tempo per scrivere test unitari per il mio codice. Quando scrivevo i test, erano cose gonfie e pesanti che mi incoraggiavano solo a pensare che avrei dovuto scrivere sempre unit test solo quando sapevo che erano necessari.

Di recente sono stato incoraggiato a utilizzare Test Driven Development e l'ho trovato una rivelazione completa. Ora sono fermamente convinto di non avere il tempo di non scrivere unit test .

Nella mia esperienza, sviluppando pensando ai test, si ottengono interfacce più pulite, classi e moduli più mirati e in genere più codice SOLID , testabile.

Ogni volta che lavoro con un codice legacy che non ha test unitari e devo testare manualmente qualcosa, continuo a pensare "questo sarebbe molto più veloce se questo codice avesse già dei test unitari". Ogni volta che devo provare ad aggiungere funzionalità di unit test al codice con elevato accoppiamento, continuo a pensare "sarebbe molto più facile se fosse stato scritto in modo disaccoppiato".


TL; versione DR :

Scrivi un test quando è probabile che il costo di scrittura del test, oltre al costo di eseguirlo tutte le volte che è necessario, sia inferiore al costo di testarlo manualmente tutte le volte che è necessario.

Ricorda però che se usi TDD, è probabile che il costo della scrittura dei test diminuisca man mano che migliorerai e, a meno che il codice non sia assolutamente banale, probabilmente finirai per eseguire i test più spesso di quanto ti aspetti.


3

Esegui il test non appena noti le regressioni o la paura di causarne alcune con le tue modifiche e senza accorgertene.

Kindle che temono, lascia che cresca a una dimensione adeguata: prima testerai, meglio è.

Nota: a seconda del ruolo svolto nel progetto, i test unitari potrebbero non essere l'unico tipo di test che si desidera scrivere.

Tutti sono giustamente ossessionati dai test unitari , a causa delle cattive pratiche di test tradizionali in passato; ma se non hai mai testato prima, dovresti davvero concentrarti sui test in generale , i test unitari da soli non risolveranno i problemi del mondo.


1
Ti vedo puntare ma non sta testando l'unità il punto di partenza di base per i programmatori di avvio. E potresti anche approfondire ciò che intendi per "test in generale". Grazie.
Lamin Sanneh,

1
Esistono almeno altri due tipi di test: test di integrazione e test di accettazione. I test unitari coprono un'unità specifica (ad es. Questa funzione di questa classe dovrebbe Frab the Fizz). Prendi in giro / stub tutti gli altri posti in cui quella classe interagisce, passandogli dati fasulli. Quando si eseguono i test di integrazione, si combinano due (o più) classi per assicurarsi che le classi vadano insieme nel modo in cui si pensa che dovrebbero. Alla fine costruisci abbastanza test da eseguire test end-to-end su tutto il tuo sistema, a volte noti come "test del fumo".
Wayne Werner,

C'è anche il test di regressione tout court. I test di regressione sono in genere più grandi dei test unitari, può richiedere un giorno per essere costruito, può implicare l'accesso ai dati dei test e ad ambienti di test speciali. In realtà i test unitari sono una versione più piccola, più elegante e più manutenibile dei test di regressione (vecchio stile).
ZJR,

1

Credo che non siano le dimensioni del progetto, ma il tipo di progetto che decide se utilizzare i test o meno.

Se stai lavorando su una prova di concetto o su qualche altro progetto in cui l'obiettivo è quello di imparare dalla codifica, non è necessario testare. Se il progetto è pensato per essere utilizzato, forse anche inviato in produzione, allora dovrebbe essere testato.

Una citazione dal "Clean Code" di Robert C. Martin : "Se è banale scrivere, è banale testare", quindi non ci sono scuse per saltare i test per programmi brevi e banali.


0

Non è davvero una questione di dimensioni, è quello che ci fai (e quanti anni ha). Se sto cercando di capire come funziona una tecnologia e sto pianificando di buttare via la cosa (la chiamiamo un picco in Scrum), scriverò semplicemente il codice senza fare molti test. Se stai pianificando di svilupparlo ulteriormente (anche se stai solo scherzando), dovresti scrivere test attorno al codice. TDD è una tecnica di progettazione ancor prima di essere una tecnica di prova. Volete avere un quadro chiaro di ciò che volete che faccia il codice prima di rimanere legati ai dettagli dell'esecuzione. Anche io NONconsiglia di provare a scrivere test unitari approfonditi su grandi quantità di codice legacy. Prova a identificare quelle parti che sono complesse (hanno un'elevata complessità ciclomatica / codice spaghetti) e quelle parti che falliscono frequentemente (saranno spesso le stesse). Come altri hanno suggerito, andrei a leggere il libro di Kent Beck su TDD e sicuramente leggerò il libro di Michael Feather. Ciò che non coprono molto è l' aspetto politico nello scrivere unit test attorno al codice. Molti sviluppatori odiano dover modificare il proprio codice per renderlo testabile e molti sviluppatori non sentono affatto la necessità di testare il codice. È qualcosa su cui dobbiamo lavorare come professione. Ogni altra disciplina ingegneristica è tenuta a dimostrare (spesso matematicamente) che il loro lavoro ha soddisfatto le specifiche. Dovremmo fare lo stesso.


-1

Vincolare un progetto nei limiti di classi o funzionalità e poi giudicare se questo è adatto per il test unitario potrebbe essere sbagliato. Ci sono numerosi vantaggi del test unitario di un'applicazione, ma la vera bellezza inizia quando devi mantenere un'applicazione o lavorare in un ambiente distribuito. Quindi la scelta viene qui. Anche una piccola modifica nel codice può causare disastri.
Vorrei non solo suggerire "Unit Testing", ma consiglierei anche di verificare la copertura del codice, assicurando che il massimo del codice sia coperto con Unit Test. La soglia per la copertura del codice non deve essere inferiore al 95% e l'obiettivo deve essere intorno al 100% . Puoi utilizzare gli strumenti per tenere traccia della copertura del codice e generare un rapporto.
Visual Studio fornisce dati sulla copertura -http://msdn.microsoft.com/en-us/library/ms182496(v=vs.80).aspx
Inoltre puoi usare NCover o dotCover.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.