Citazione da: "cdimauro"Lo unit testing serve a documentare il codice fornendo proprio tutti gli esempi necessari a capire cosa si aspetta uno strumento (API, funzione, classe), in modo che l'utilizzatore ne sia pienamente consapevole in poco tempo.No, lo unit test non serve a documentare il codice, se tu lo usi per documentare ne fai uso improprio (o secondario), ma non serve a quello.
Lo unit testing serve a documentare il codice fornendo proprio tutti gli esempi necessari a capire cosa si aspetta uno strumento (API, funzione, classe), in modo che l'utilizzatore ne sia pienamente consapevole in poco tempo.
Citazione da: "cdimauro"CitazioneInoltre breaka l'encapsulation se i tuoi unit test (e lo fanno, dato che in un linguaggio dynamic typing lo si deve fare) testano anche le funzioni interne del codice e non solo l'interfaccia.Non ho capito la parte evidenziata. Potresti essere più chiaro, per favore?Intendo l'implementazione. In un linguaggio dynamic typing non hai l'ausilio del compilatore o interprete per testare la bontà di ogni singola riga di codice, quindi devi fare delle unità di testing anche per l'implementazione. In un linguaggio static typing è sufficiente solo testare l'interfaccia, perché alla fine gli effetti del typing si propagano nell'implementazione. In realtà sarebbe più corretto dire che l'implementazione è testata tramite il constraint dell'interfaccia.
CitazioneInoltre breaka l'encapsulation se i tuoi unit test (e lo fanno, dato che in un linguaggio dynamic typing lo si deve fare) testano anche le funzioni interne del codice e non solo l'interfaccia.Non ho capito la parte evidenziata. Potresti essere più chiaro, per favore?
Inoltre breaka l'encapsulation se i tuoi unit test (e lo fanno, dato che in un linguaggio dynamic typing lo si deve fare) testano anche le funzioni interne del codice e non solo l'interfaccia.
Citazione da: "cdimauro"E' anche per questo che non lo faccio: è troppo noioso scrivere documentazione, soprattutto sapendo che hai fatto un sacco di lavoro in tal senso mettendo in piedi una buona suite di test (che, nel mio caso, generalmente è circa il doppio del codice di produzione).Sono due lavori totalmente diversi. Ti faccio un esempio banalissimo per farti capire che unit testing != documentazione:Vogliamo testare una funzione per l'EOF nei file, lo facciamo con un file fisso di tot caratteri, dopo quei tot caratteri ci aspettiamo EOF, nel caso di feof() del C è:while(1) { /* code */ if ( feof(infile) ) break;}Mentre il TestEOF() della mia dsarlib (nomi inventati) è:while( ! TestEOF(infile) ) { /* code */}La posizione dell'EOF lo testo conteggiando il numero dei caratteri prima, se usassi loop diversi ci sarebbe un numero minore o maggiore rispetto a quello corretto.Mi sai dire la differenza di come io nella mia libreria ho implementato il testing dell'EOF, a primo colpo d'occhio? Scommetto che senza una buona documentazione non ci riusciresti :-) (ed è normale).Semplicemente il feof() del C ti dice se tu sei esattamente sulla posizione dell'EOF, mentre TestEOF() ti dice se il prossimo getch() fallirà perché sarà l'EOF.L'unit testing ti aiuta a verificare se è corretto per come lo hai voluto implementare tu, ma per comunicarlo al programmatore devi documentarlo! Onestamente mi auguro di non trovare programmatori che pretendano che io capisca una certa implementazione leggendo il codice del testing come quello sopra!
E' anche per questo che non lo faccio: è troppo noioso scrivere documentazione, soprattutto sapendo che hai fatto un sacco di lavoro in tal senso mettendo in piedi una buona suite di test (che, nel mio caso, generalmente è circa il doppio del codice di produzione).
function TestLogin() { AssertException('StringTooSmall', 'Login', '', 'Prova!'); AssertException('StringTooLong', 'Login', str_repeat('N', 31), 'Prova!'); AssertException('StringTooSmall', 'Login', 'Pippo', ''); AssertException('StringTooLong', 'Login', 'Pippo', str_repeat('N', 31)); NewUser(); Login('Pippo', 'Pluto');}
Citazione da: "cdimauro"Comunque capisco anche il tuo punto di vista. Certamente se dovessi distribuire il mio codice all'esterno sarei sicuramente costretto a scrivere la documentazione (perché è quello che normalmente si aspettano i programmatori; in particolare quelli che non sono avvezzi allo unit testing), e in tal caso opererei come hai scritto qui alla fine.Posso chiederti, per curiosità, chi legge i file di unit testing a scopo di documentazione? :O
Comunque capisco anche il tuo punto di vista. Certamente se dovessi distribuire il mio codice all'esterno sarei sicuramente costretto a scrivere la documentazione (perché è quello che normalmente si aspettano i programmatori; in particolare quelli che non sono avvezzi allo unit testing), e in tal caso opererei come hai scritto qui alla fine.
Citazione da: "cdimauro"Scrivere documentazione in corso d'opera è un'emerita stupidaggine: ci si ritroverebbe con due "codici" da gestire, mantenere, aggiornare, e che potrebbero anche trovarsi non aggiornati allo stesso tempo (il codice fa una cosa, e la documentazione ne dice un'altra). Cosa tutt'altro che scontata.Il problema di syncare codice e documentazione è un problema reale, ma evitare di farlo fidati che è peggio
Scrivere documentazione in corso d'opera è un'emerita stupidaggine: ci si ritroverebbe con due "codici" da gestire, mantenere, aggiornare, e che potrebbero anche trovarsi non aggiornati allo stesso tempo (il codice fa una cosa, e la documentazione ne dice un'altra). Cosa tutt'altro che scontata.
Però non mi hai detto se a colpo d'occhio hai capito come è stato implementato il test dell'EOF.
Ci sono situazioni complesse in cui non te ne puoi uscire con un semplice assert.
Inoltre ci sono cose che non puoi documentare con l'unit testing, come degli internal che fanno riferimento a fatti di performance. Per esempio io pretendo di sapere se GC.Collect() mi invoca uno stop the world oppure è continuo o concorrente, perché nel primo caso sceglierei i momenti più adatti per farlo. Oppure ogni quanto i dati vengono automaticamente flushati in uno stream.
L'unit testing serve per verificare la robustezza delle interfacce, e preferisco lasciarlo per quello.
Per la documentazione non devi mica scrivere un tema di 50 pagine, bisogna essere rigorosi, concisi ed inambigui. L'ultimo è importante e puoi raggiungerlo solo con i primi due
Logicamente di tutto quello che avete detto non è che abbia una grande esperienza, anche perchè con Python non ho neanche iniziato,
posso solo dire che per i miei progetti non posso non documentare durante la stesura del codice (parlo di documentazione rivolta principalmente a me stesso e per le miei librerie) perchè a distanza di mesi non sarei più in grado di capire a colpo d'occhio cosa fa questo o quello, con quali parametri e limitazioni.Poi man mano che effettuo delle modifiche modifico la documentazione (all'interno del codice stesso) e metto in coda una serie di brevi commenti su ciò che ho modificato/aggiunto.Faccio questo perchè altrimenti non ne vengo più fuori
Se poi devo pubblicare qualcosa è il momento di stendere la user doc, ma questo solo ed esclusivamente quando il progetto è concluso e stabile altrimenti diventa un secondo lavoro.