posts - 644, comments - 2003, trackbacks - 137

My Links

News

Raffaele Rialdi website

Su questo sito si trovano i miei articoli, esempi, snippet, tools, etc.

Archives

Post Categories

Image Galleries

Blogs

Links

Unit Testing, Dijkstra e i Community Days

Durante gli scorsi Community Days del 21 e 22 Giugno si è accesa una discussione riguardo ai Dynamic Languages ed in particolare al fatto che questi possano sopperire al problema dei Run-time errors con l'uso estensivo di Unit Testing.

Personalmente mi sono "acceso" a favore degli errori di compilazione che sono i miei migliori amici, scottato nel passato da brutte esperienze a base di variant, vbscript, javascript e memore del prezioso aiuto che invece il compilatore c++ mi ha sempre dato. Non nego per questo l'utilità dei linguaggi dinamici, per esempio per propositi di amministrazione di una rete al posto del più vetusto Windows Scripting Host, magari a fianco della nuova shell Monad.

La discussione ha toccato poi lo Unit Testing e ho "inutilmente" cercato di spiegare come ci siano innumerevoli casi in cui purtroppo sia totalmente inutile e impraticabile. Purtroppo ogni giorno ne ho un riscontro, per esempio solo una settimana dopo l'evento, grazie ad una segnalazione sui newsgroup, ho riscontrato un problema non identificabile con Unit Testing nella mia collection http://www.codeplex.com/RafCollection. Ho implementato il metodo EndNew in modo tale da lanciare una ArgumentOutOfRangeException per indici negativi ... sembra tutto ok e confortato da unit testing. Invece la GridView del Framework 2.0 chiama stranamente EndNew con index = -1 e lo Unit Testing si rivela ovviamente inutile.

Non per questo nego l'utilità di Unit Testing che in molti casi permette una validazione (che nulla ha a che fare con la dimostrazione di correttezza) del codice.

Odio le mode che vedono Unit Testing come panacea di tutti i mali e Edsger Dijkstra, uno dei padri degli algoritimi dell'ottimizzazione (che ricordo bene per aver implementato uno dei suoi algoritmi in C#) aveva già avvertito con un profetico “Program testing can be used to show the presence of bugs, but never to show their absence!”.

Print | posted on martedì 3 luglio 2007 02:43 |

Feedback

Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Tu parli di Unit Testing e non di TDD, quindi immagino intendi la scrittura dei test dopo la scrittura del codice per verificarne la funzionalità. Su questo non ho molta esperienza perchè sviluppo quasi esclusivamente in TDD.
Quello che ti posso dire è che i test non garantiscono l'assenza di bug, infatti, nei progetti che ho realizzato c'erano, ma riducono il tempo di risoluzione del bug in quanto il codice ha un design migliore e quindi è molto più semplice localizzare il bug. Inoltre utilizzo molto meno il debugger (molto meno non significa che non lo utilizzo diciamo un 80% di meno).
Fino ad ora non ho trovato ancora un caso di codice non testabile: ho sviluppato software in multithreading, con socket, db, ecc. e quindi per l'affermazione codice intestabile vorrei degli esempi concreti.
Infine ho provato alcuni frameword (NUnit, MbUnit, Quality Tools della Microsoft, ecc.) e per ora l'accoppiata migliore è MbUnit + TestDriven.NET per lanciare i test.
03/07/2007 13:00 | Antonio Ganci
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Lo sto applicando in tutti i progetti da quattro anni a questa parte, l'unica differenza rispetto a prima è un tempo maggiore alla prima release, ma un grosso risparmio di tempo nella gestione delle modifiche risoluzione bug, ecc.
I casi che hai citato li ho affrontati in questa maniera:
- Pattern MVP: non testo i singoli clic del mouse, ma riduco al minimo il codice della view
- sulla conversione dovrei capire meglio, ho fatto diverse conversioni di formati senza dover "riscrivere" parser xml o browser
- Quanto si usa una libreria di terzi non la testo direttamente ma uso test di comportamento e non di stato
- Sulle performance dovrei capire meglio il tuo problema ho sviluppato software critici nelle performance, ma non ho avuto i problemi che dici
Non scrivo software prevalentemente algoritimico, gli unit test sono di due tipi:
- testo lo stato (la assert su un valore di una property, o il ritorno di un metodo, ecc.)
- testo il comportamento: tramite mock o stub che non testano il risultato di un algoritmo ma l'interazione di oggetti
03/07/2007 15:24 | Antonio Ganci
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Volevo solo aggiungere:
Il TDD non è per me la soluzione di tutti i mali, ma uno strumento molto utile e non basta da solo a determinare il successo di un progetto.
Nel team dove ho lavorato e dove lavoro ho notato che non a tutti va bene come metodo di sviluppo (secondo me più un preconcetto che per un motivo veramente valido) ma credo che in futuro si diffonderà molto.
03/07/2007 15:30 | Antonio Ganci
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Ancora una standing ovation per te! Mitico Raf!
03/07/2007 18:02 | Mario Duzioni
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

@Claudio. Che ti piaccia l'ho capito. Che su tanti bei libri si trovino belle parole a favore di metodologie, strategie, pattern e quant'altro fa parte della moda corrente e passi.
Ma a parte le rispettive convinzioni personali, non vedo in modo *pratico* come sia applicabile agli esempi che ho fatto (e sono solo alcuni).
Per *pratico* intendo che il vantaggio deve essere qualitativo ma anche di costi perché il cliente che paga vuole guarda il totale (che comprende certamente l'intero ciclo di vita del software, certamente comprensivo anche della manutenzione).

Ripeto per l'ennesima volta che non sto dicendo non sia utile Unit Testing, ma che non può essere una base per validare un software. È solo uno dei tanti sistemi che può rivelarsi più o meno utile a seconda dei casi.

@Mario. Ma c'è qualcuno che la pensa come me allora :)
03/07/2007 18:21 | Raffaele Rialdi
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Raffaele io non lavoro molto su gestionali, fino all'anno scoro lavoravo in ambito Formula 1 e il software che producevamo girava ai box e quindi credimi che avevamo problematiche di performance e affidabilità non indifferenti. Tipo rendering di grafici complessi in realtime, analisi in tempo reale dei dati della macchina, ecc.
Ora lavoro in ambito finanziario e mi occupo dell'analisi dei dati di mercato e anche qui la parte che seguo è poco gestionale.
Sono applicazioni complesse sia dal punto di vista UI che algoritmico ed uso diverse librerie terze parti.
Ora dobbiamo metterci d'accordo su cosa intendiamo per test:
Quando realizzo il codice che visualizza un grafico, io NON testo i pixel che vanno a video, ma mi fermo a testare la chiamata di una routine che ad esempio disegna una line e di cui suppondo pragmaticamente che funzioni (visto che l'ha scritta la microsoft ;-)).
Se utilizzo una libreria terze parti ci accedo tramite wrapper prodotti da me e il testing si ferma a controllare che ho fatto una chiamata la quale poi si occuperà a sua volta di chiamare la libreria esterna, ecc.
Ci sono poi altri tipi di test differenti dagli unit test che non sempre si possono fare in automatico come i test di accettazione, usabilità, ecc.
Uno Unit Test deve essere il più indipendente possibile dal PC su cui gira nel senso che non deve dipendere da hardware specifico, file system o database.

03/07/2007 18:48 | Antonio Ganci
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Finalmente qualcuno che fa qualcosa di diverso dal solito gestionale :)

Tracciare una riga solo perché le coordinate sono corrette non assicura affatto che il *risultato complessivo* sia quello voluto. In un controllo GDI hai il problema dell'erasebackground, delle paint sui contenitori (user control, panel, etc.) , del double-buffering. Ci sono test che devi effettuare guardando la trace di Spy++ e non puoi dare per scontato che la chiamata alla primitiva grafica sia la scelta migliore perché dipende dal contesto in cui la usi.
Il fatto di fermarsi a controllare se l'input verso la blackbox successiva sia corretta, non è sufficiente a garantire che il sistema nella sua interezza funzioni. Il funzionamento non gode della proprietà transitiva... se i sistemi A e B funzionano non necessariamente A+B funzionano insieme! Può valere per per alcuni sistemi ma non per tutti.

Sulla dipendenza dell'hardware specifico la scelta di cui parli è coerente con unit testing. Se però parliamo di performance il discorso non può fare a meno di essere specifico all'hardware... l'isolamento dalla tecnologia la otteniamo strutturando a layer l'applicazione che però in ogni suo componente deve essere molto ben conscia della tecnologia specifica che usa per sfruttarla al meglio (o evitarne i punti deboli).
03/07/2007 19:36 | Raffaele Rialdi
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Iniziamo a convergere sono contento :)
Ti parlo di una problematica concreta che ho avuto: inzialmente i grafici li visualizzavo utilizzando le GDI+, ma la quantità di dati che dovevo visualizzare era tale che le performance erano troppo scarse (meno di un frame al secondo).
Allora ho sostituito le GDI+ con le vecchie GDI le quali hanno dato un miglioramento delle performance notevole.
Nell'applicazione questo cambiamento ha comportato relativamente poco lavoro, in pratica ho dovuto scrivere una classe che implementa un'interfaccia e i test non li ho toccati perchè si fermavano alla chiamata dei metodi dell'interfaccia.
Con ciò voglio dire che Spy++, ecc. sono strumenti che ancora uso, ma che esulano dallo unit test secondo il mio punto di vista.
A volte dopo aver scritto tutti i test mi capita di lanciare l'applicazione la quale non fa assolutamente nulla perchè mi sono dimenticato di far partire, per esempio, l'evento Click dalla view.
Quindi lo unit test non garantisce che l'applicazione funzioni senza bug, ma aiuta a scrivere classi con basso accoppiamento e alta coesione.
Non dico che senza unit test questo non sia possibile, ma per quanto mi riguarda se non scrivo i test corro il rischio di cadere in tentazione :-)
Sono molto pragmatico nella scrittura del software e non credo ASSOLUTAMENTE nel silver bullet.


03/07/2007 19:53 | Antonio Ganci
Gravatar

# TDD, UnitTesting ed il significato di

03/07/2007 20:54 | TheDuzBlog! ;-p
Gravatar

# TDD, UnitTesting ed il significato di

03/07/2007 20:57 | TheDuzBlog! ;-p
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

@Antonio. Cominciamo a convergere sul serio ... quello che scrivi mi trova concorde.
Sul guadagno dell'isolamento dei layer non ci sono dubbi ma questo prescinde dal fatto di lavorare in TDD, in modo tradizionale o qualsiasi altra metodologia.

Nel silver bullet non ci credo ovviamente neanch'io ma il discorso era proprio nato dal fatto che Unit Testing viene visto come sistema per controbilanciare ai più frequenti errori di runtime dei linguaggi dinamici... cosa a cui ovviamente non credo nel modo più assoluto.

@Luca
- purtroppo come ho scritto ad Antonio durante i community days veniva indicata come strada l'uso di unit testing per contrastare gli errori di runtime che inevitabilmente arrivano per l'assenza del controllo di errori da parte del compilatore. Quindi il "nessuno" che scrivi in realtà è "qualcuno".
- il disegno può essere guidato da un test solo se il test è realizzabile. Il disegno può essere anche evidenziato in altro modo.
Se il test è realizzabile, allora è una questione di scelta e gusto personale. Se non è realizzabile, diventa una scelta diabolicamente errata.

- Mi sembra che sulla validazione stiamo parlando della stessa cosa. Non concordo invece sulla definizione dello unit testing:
- unit testing *in alcuni casi* permette una validazione funzionale del singolo componente ma NON di correttezza del software nella sua interezza.
Per affermare la correttezza del software è necessario che vi sia la funzionalità complessiva data non solo dal corretto funzionamento di tutti i componenti del sistema ma anche dal fatto che collaborino tra loro. Antonio prima con il mancato collegamento del click del bottone alla funzionalità, ha fatto un esempio lampante.
03/07/2007 21:07 | Raffaele Rialdi
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Luca,
- dimentichi non sono io che dico che lo unit testing non è uno strumento completo. Il test di funzionalità di un requisito sono il primo a dire che è ben altra cosa ed è indispensabile.

- ho già fatto molti esempi negli altri post in cui lo unit testing non è possibile e infatti con Antonio siamo arrivati ad una convergenza. Qui il design non c'entra nulla, è semplicemente impossibile o non conveniente fare unit testing automatizzato su certe funzionalità.

- si certo, ci starò lontano a chi si spara sui piedi :) ... ma di fatto sui linguaggi dinamici c'è un gran fermento. Io ne riconosco i pregi in certi campi di applicazione ma c'è chi pensa di farne uno strumento primario e come ho già detto non concordo. IMHO è una questione di mode.
03/07/2007 21:54 | Raffaele Rialdi
Gravatar

# Unit testing non

04/07/2007 00:09 | makka
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Abbasso un attimo i toni della conversazione...
non è che tra qualche tempo ci troveremo tutti a rifare mille discorsi paralleli quelli che l'umanità ha già affrontato riguardo al metodo scientifico con proposizioni tipo: se non puoi realizzare un programma in grado di falsificare il tuo codice con dei bug allora il tuo non è vero codice! Oppure il tuo codice è vero codice solo perchè non è ancora stato scritto un codice che approssima meglio la soluzione del problema!... e via di questo passo...
...si ok mi rimetto all' ombra che il sole mi fa male evidentemente.... :)
ciao e buone vacanze a tutti!

20/07/2007 18:38 | Stefano Padovan
Gravatar

# re: Unit Testing, Dijkstra e i Community Days

Ciao Stefano,
mi piace solo valutare in modo critico (nel vero senso del termine) ciò che viene considerata pratica consolidata e indiscutibile.
Tante volte anche nel nostro mestiere certe cose diventano moda e come tali non c'è neppure il coraggio di criticarle.

Da parte mia c'è solo la voglia di tenere un equilibrio facendo tesoro delle esperienze acquisite, tutto qui.
31/07/2007 02:07 | Raffaele Rialdi
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET