Quanto deve essere grande il mio progetto per farmi testare? [chiuso]

86

Suppongo che il mio progetto sia disaccoppiato quanto basta per consentire il test dell'unità. Ma quanto è grande, esattamente, in termini di clase e funzioni, il mio progetto deve essere per rendere utile il test unitario?

Tutti commettiamo errori e nessuno è perfetto, ma mi considero un programmatore decente per gestire gli errori dei piccoli progetti con il passaggio. Oppure il test unitario è una necessità irrisolta, indipendentemente dalle dimensioni del tuo progetto?

    
posta Lamin Sanneh 08.08.2012 - 09:44
fonte

12 risposte

205

Il tuo progetto è già abbastanza grande.

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

    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());
        }
    }
    
risposta data 08.08.2012 - 09:55
fonte
109

Non ho mai acquistato l'idea "devi testare tutto", anche se ci sono sicuramente persone 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 si rompano.
  2. Aiutarti a progettare interfacce sensibili per le tue classi (dal momento che ti costringe ad essere un cliente per il tuo codice).
  3. Aiutare a documentare come verrà utilizzato il codice.

Fondamentalmente è necessario pesare il tempo che ci vorrà per scrivere & mantenere i test contro questi fattori.

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

    
risposta data 08.08.2012 - 10:04
fonte
34

È semplice: non hai bisogno di test delle unità se scarterai il programma dopo averlo eseguito una sola volta.

Se questo ti sembra eccessivo, considera quale sarebbe 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? Devo iniziare a scrivere dei test?" Ora, i programmatori sono notoriamente cattivi nel predire il futuro, e sono notoriamente cattivi nel giudicare le proprie capacità. Il codice che ti appare cristallino ora diventerà incomprensibile, anche a te, anche aspettando un mese. Un progetto che sei assolutamente sicuro di non essere mai più utilizzato, e che ti mantenga solo nella remota possibilità che potresti voler vedere come hai risolto qualcosa prima, sarà richiesto di nuovo, e riceverà richieste di modifica.

È quindi molto probabile che tu possa giudicare male se il test sia utile o meno, e quando inizi a richiedere dei test, non sei già al 100% sicuro di quale sia la semantica esatta da testare. Poiché ritengo che tutti, tranne i banali programmi una tantum, traggano profitto dai test unitari, ritengo che il costo dello sforzo di spesa per test che non vengono mai eseguiti di nuovo sia trascurabile rispetto ai rischi di estendere codice non testato e mal compreso.

    
risposta data 08.08.2012 - 09:56
fonte
22

Qualche tempo fa ho trovato un bel post: Perché il test dell'unità accelera lo sviluppo . Può aiutarti a rispondere alla domanda.

...What if the codebase... was provided with a substantial set of unit tests. A set that would say : “if all tests succeed, I guarantee that code still does what it should do” and if a test fails it exactly shows you where some behavior is broken . This is great, I could change the code to add things I want without wandering if the code still does what it should do, I just run the... tests and I have faith. This is a great world to be in as a software engineer. I noticed that I could advance way faster...

I have “faith”.

This is probably the most important reason why unit tests speed up development in a enterprise context.

I can trust that everything still works if all tests pass. If tests fail they will point out exactly where the problem lays...

...you have to have a high unit test coverage and good unit tests. When these conditions are respected you’ll find yourself in a situation that the effort for adding new functionality ‘s is almost independent of the size of the application and that in the long run it will speed up development.

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

  • modifica e prega,
  • copertina e modifica.

Non importa quanto grande è il codice base.

    
risposta data 08.08.2012 - 11:47
fonte
18

In base a nella sua risposta alla domanda Stack Overflow Quanto sono profondi i test di unità? , dovresti testare il codice che tendi a sbagliare.

If I don't typically make a kind of mistake (like setting the wrong variables in a constructor), I don't test for it.

    
risposta data 08.08.2012 - 15:02
fonte
5

I test unitari sono implementati per risparmiare tempo e migliorare:

  • bug tracking
  • refactoring e / o riscrittura del codice
  • test di integrazione
  • test di regressione, ecc.

È obbligatorio scrivere test unitari per parti relativamente complesse del programma.

Se sei sicuro che scrivere test di unità ora non salverà il tuo tempo in futuro, puoi saltarlo. Tuttavia, non si sa mai, e personalmente non riesco a pensare a un caso quando è più economico (nel senso di tempo, denaro e nervi) a non scrivere test unitari ma a fare invece tutti i test manualmente.

    
risposta data 08.08.2012 - 09:58
fonte
4

"Se devo testare questo dispositivo" di solito si può rispondere rispondendo alla seguente domanda: "È importante che questa funzione funzioni correttamente, ed è importante per me sapere quando smette di funzionare?"

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

    
risposta data 08.08.2012 - 12:52
fonte
4

A meno che tu non abbia intenzione di scrivere il codice senza testarlo, dovrai sempre sostenere il costo del test.

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

Se il costo di scrittura di un test unitario è di 2 minuti e il costo dell'esecuzione del test dell'unità è praticamente pari a 0, il costo del test manuale del codice è di 1 minuto, quindi si interrompe anche quando si esegue il test due volte.

Per molti anni ho capito male che non avevo abbastanza tempo per scrivere test unitari per il mio codice. Quando ho fatto dei test, erano cose gonfie e pesanti che mi hanno solo incoraggiato a pensare che avrei dovuto scrivere solo unit test quando sapevo che erano necessari.

Recentemente sono stato incoraggiato a utilizzare Test Driven Development e ho scoperto che si trattava di una rivelazione completa. Ora sono fermamente convinto di non avere il tempo non per scrivere test unitari.

Nella mia esperienza, sviluppando con i test in mente si finiscono con interfacce più pulite, classi più focalizzate e amp; moduli e generalmente più SOLID , codice verificabile.

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 un accoppiamento elevato, continuo a pensare che "sarebbe molto più semplice se fosse stato scritto in modo disaccoppiato".

TL; DR versione:

Scrivi un test quando il costo di scrittura del test, più il costo di eseguirlo tutte le volte che è necessario, è probabilmente inferiore al costo di testarlo manualmente tutte le volte che è necessario.

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

    
risposta data 08.08.2012 - 16:54
fonte
3

Prova non appena osserva le regressioni o teme di causare alcuni con le tue modifiche e senza accorgertene.

Accendi questa paura, lasciala crescere di dimensioni adeguate: prima esegui i test, meglio è.

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

Ognuno è giustamente ossessionato dai test delle unità , a causa delle cattive pratiche di test tradizionali in passato; ma se non hai mai provato prima, dovresti concentrarti su testing in generale , i test di unità da soli non risolveranno i problemi del mondo.

    
risposta data 08.08.2012 - 10:23
fonte
1

Credo che non sia la dimensione del progetto, ma il tipo di progetto che decide se utilizzare o meno il test.

Se stai lavorando su un proof of concept, o su qualche altro progetto in cui l'obiettivo è imparare dalla codifica, non è necessario eseguire test. Se il progetto è pensato per essere utilizzato, forse anche inviato in produzione, dovrebbe essere testato.

Una citazione da "Codice pulito" di Robert C. Martin : "Se è banale da scrivere, è banale per testare ", quindi non ci sono scuse per saltare il test per programmi brevi e banali.

    
risposta data 09.08.2012 - 08:28
fonte
0

In realtà non è una questione di dimensioni-- è ciò che fai con esso (e quanti anni ha). Se mi gira intorno imparando come funziona una tecnologia e pianifico di buttare via la cosa (lo chiamiamo un picco in Scrum), farò solo il codice senza fare molti test. Se stai pianificando di svilupparlo ulteriormente (anche se stai solo girovagando), dovresti scrivere dei test sul codice. TDD è una tecnica di progettazione ancor prima che sia una tecnica di prova. Vuoi avere una chiara immagine di ciò che vuoi che il codice faccia prima che ti leghi nei particolari dell'esecuzione. Vorrei anche NOT consigliare di provare a scrivere test unitari estesi su grandi quantità di codice legacy. Cerca di identificare quelle parti che sono complesse (hanno un alto livello di complessità ciclomatica / codice spaghetti) e quelle parti che falliscono frequentemente (spesso saranno le stesse). Come altri hanno suggerito, andrei a leggere il libro di Kent Beck su TDD e sicuramente leggerò il libro di Michael Feather. Quello che non coprono molto è l'aspetto politico per scrivere test unitari sul codice. Un sacco di sviluppatori odiano dover modificare il loro codice per renderlo testabile, e molti sviluppatori non sentono la necessità di testare il codice. È qualcosa su cui dobbiamo lavorare come professione. Ogni altra disciplina ingegneristica è necessaria per dimostrare (spesso matematicamente) che il loro lavoro ha soddisfatto le specifiche. Dovremmo fare lo stesso.

    
risposta data 08.08.2012 - 23:57
fonte
-1

Vincolare un progetto nei limiti di classi o funzionalità e quindi giudicare se questo è adatto per il test di unità potrebbe essere sbagliato. Esistono numerosi vantaggi dell'unità di test di un'applicazione, ma la vera bellezza inizia quando devi mantenere un'applicazione o lavorare in un ambiente distribuito. Quindi la scelta arriva qui. Anche un piccolo cambiamento nel codice può causare disastri.
Non suggerirei solo "Test unità", ma raccomanderei anche di controllare la copertura del codice, assicurando che il codice sia coperto al massimo con Test unità. La soglia per la copertura del codice non deve essere inferiore a 95% e l'obiettivo deve essere intorno a 100% . Puoi cercare strumenti per tracciare la copertura del tuo codice e generare un rapporto.
Visual Studio fornisce i dati di copertura - link
Inoltre puoi usare NCover o dotCover.

    
risposta data 09.08.2012 - 02:00
fonte