test driven development @ xe.net
DESCRIPTION
Test Driven Development @ Xe.NetTRANSCRIPT
T.est D.riven D.evelopmentTDD or not TDD, that is the question...
» Mauro ServientiMicrosoft MVP - Visual C#http://blogs.ugidotnet.org/[email protected]
Primo semestre 2009in collaborazione con:
Who am I?
blog: http://blogs.ugidotnet.org/topics
email: [email protected]
web: https://mvp.support.microsoft.com/profile/mauro
community: www.xedotnet.org, www.ugidotnet.org
Mauro Servienti
www.xedotnet.org 427/02/2009
» I prossimi Meeting
• .NET Micro Framework - (Virtual Meeting)• 30/4/2009 – Online ore 21:30 – MIRCO VANINI
• NetTiers & Code Generation: Rapid Application Prototyping• 8/5/2009 – Mestre, Novotel Castellana – DAVIDE SENATORE
• PROGRAMMING WITH C# 3.0• 5/6/2009 – Mestre, Novotel Castellana – ANDREA DOTTOR
Agenda
» Perchè non testiamo e quali sono le conseguenze;» Perchè testiamo e quali sono i vantaggi;» Come il testing modifica il nostro modo di scrivere
codice, e perchè io ritengo sia un bene;» Ha senso cercare di testare tutto?» Anatomia dello Unit Testing;» Introduzione a metodologie fortemente basate sul
testing: TDD e Test First;» TDD: ne vale la pena?
INTRODUZIONE (FORSE…)
Welcome to the real world...
Sondaggio
» Su le mani... E non mentite
Usate Unit Test(s)? No?, perchè?
Avete mai fatto TDD? No?, perchè?
Partiamo dalla fine...
» Ammettiamolo testare costa, e costa un sacco...• In molti casi gli strumenti sono ancora immaturi;• Non abbiamo un “compilatore” che, se non
scriviamo i test, non compila...;• Non percepiamo il valore dei test perchè non
misuriamo quanto ci costano i bug;
» Shawn Farkas (il saggio mangiatore di caramelle) una volta disse...
Quale è il problema:
» Noi scriviamo stupidaggini ;-):• E’ inevitabile il software contiene bug;
» Noi non scriviamo la documentazione...:• Il problema non è detto che sia la pigrizia e tenere la
sincronia è veramente oneroso;» Qualcuno ci chiede le modifiche... e le vuole ieri:• E’ colpa nostra, abbiamo abituato noi il cliente a tempi
di risposta rapidi;• Ci limitavamo a scrivere la funzionlità... E i bug? Dopo..
» Purtroppo ci tocca modificare codice “legacy”;
Possiamo arginarlo...?
» Scriviamo stupidaggini:• Keep it simple: possiamo asserire che se n parti
funzionano singolarmente allora funzioneranno insieme? Si, quello che non sappiamo è se il prodotto sarà quello atteso... ma è già un inizio;
• Single Point Of Responsability: non diamo troppe responsabilità al nostro codice, anzi diamone una sola;
• Compisition, composition, composition: creare sinergia tra i componenti.
Possiamo arginarlo...?
» Noi non scriviamo la documentazione:• Qualcuno dice che il codice è la documentazione,
secondo me è sbagliato, ma...:• La documentazione è necessaria;• La documentazione costa (in termini di fatica e non solo);• Quindi perchè non scrivere un buon codice che sia parte
intergrante della documentazione?
• Facciamo un parallelo con il Code Coverage:• 100% (C.C.) : 20% (C.C.) = Buon Codice : “Cattivo” Codice• Un buon codice non è la documentazione ma è
nettamente meglio come il 100% di CC non è garanzia di buon testing...ma il 20% è certezza di non testing...;
Possiamo arginarlo...?
» Qualcuno ci chiede le modifiche... e le vuole ieri;» Purtroppo ci tocca modificare codice “legacy”;
• Questo è il vero problema, noi non abbiamo...
…CONFIDENZA
Quello sconosciuto del nostro codice...
Confidenza, so what?
» Noi non conosciamo il nostro codice:• Quante volte aprite una solution vecchia di sei mesi
e la prima domanda che vi fate è: funzionerà...?• Quante volte “mettete mano” a codice:• Vecchio: perchè il cliente vi chiede una modifica;• Altrui: perchè qualcuno del team è semplicemente
ammalato;
• E vi chiedete: ma cosa si spaccherà?• Lo sapete già che si spaccherà... , quello che non sapete
è dove...
Confidenza, so what?
» Chi ha confidenza con il codice?• Il codice stesso...• Quindi perchè non scrivere codice che ci garantisca
la confidenza?• Fosse facile...
» Perchè ci serve la confidenza?• Regressioni, regressioni e regressioni;
Demo
COME IL NOSTRO CODICE SI MODIFICA PER “ADEGUARSI” AI TEST:DEPENDENCY INJECTION
Testing, Architettura e Design:
» Cosa abbiamo visto:• Siamo partiti da codice non testabile;• L’impossibilità di non testare è uno smell:• Questo ci ha detto che il design probabilmente non era dei
migliori, se non è facilmente testabile viola il SPoR Princ.;
• Abbiamo ridisegnato con in mente il test:• Abbiamo ottenuto qualcosa di facilmente testabile;• Abbiamo migliorato il design;
» I test migliorano il design? Non necessariamente ma sono sicuramente un buon giudice
Ci sono test e test...
» Unit Test(s):• unit == unitario;• Hanno lo scopo di testare una singola funzionalità alla
volta;• Indipendenti: ogni singolo test vive (deve) di vita propria;• Testano il comportamento non l’implementazione;• Devono essere minimali (altrimenti smell);
» Integration Test(s):• Le singole parti che funzionano, perchè testate, devono
dimostrare di lavorare correttamente anche insieme;• Dagli Unit Test(s) ereditano l’indipendenza;
Anatomia: “AAA” keep it simple
» In ottica keep it simple un test deve rispettare la regola AAA:• Arrange: è la fase di setup del test;• Act: è la fase in cui viene eseguita l’operazione sotto
test;• Assert: è la fase in cui vengono verificare le
assunzioni;» Perchè un test sia comprensibile e utile, anche la
terminologia è importante:• Expected, Target e Actual;
Gli strumenti essenziali
» Ci sono casi in cui dobbiamo testare oggetti che hanno parecchie dipendenze e rischiamo di dedicare troppo tempo alla scrittura dei test (che poi devono essere anche manutenuti)...• Mock: è un oggetto fittizio che mima il comportamento
di un altro, il comportamento è verificabile (Assert);• Stub: è un oggetto fittizio che mima passivamente il
comportamento di un altro in maniera non verificabile;• Partial Mock: è un oggetto che eredita parte del
comportamento dall’oggetto che impersona, il comportamento è verificabile;
Demo
MOCKING IS THE WORD <CIT.>
TDD: INTRODUZIONE
Come il testing, fatto prima, modifica il nostro modo di fare tutto?
Anatomia
» Si scrive il test:• Test Barra rossa, garantita ;-)
» Si implementa la singola funzionalità:• Test Barra verde?;
» Refactoring, se necessario:• Test Barra???
» Questo processo:• porta a far emergere il design;• Aiuta a focalizzarsi sui requisiti;
Come procedo...
» Ma come arriviamo a definire cosa dobbiamo realizzare?• Intervista con il cliente: spesso e volentieri con
l’operatore non con l’IT manager del cliente;• Le User Story;• La formalizzazione del processo in un linguaggio
comprensibile all’utente... niente UML ;-)
TDD - UN ESEMPIO PRATICO
Mettiamoci alla prova: IMessageBroker
Le Storie
» l'utente deve essere in grado di fare il Dispatch di un messaggio;
» l'utente deve essere in grado di sottoscrivere un messaggio sulla base del tipo del messaggio stesso;
» l'utente deve essere in grado di fare l'unsubscribe di uno specifico handler;
» l'utente deve essere in grado di fare l'unsubscribe a tutte le subscription sulla base del tipo del messaggio;
» l'utente deve essere in grado di fare l'unsubscribe a tutte le subscription che il subscriber ha fatto a prescindere dal tipo di messaggio e dall'handler stesso;
» Il dispatch di un messaggio deve notificare tutti i subscriber;
Demo
LET’S GO LIVE...
Come procedo...
» È stato difficile? Sni...• Serve esperienza, parecchia, per essere produttivi;• Servono gli strumenti adatti:• Tool di refactoring evoluti;
» A cosa porta:• Design, design e design.• Ma è buon design? Non è detto, il rischio è che sia un
design focalizzato per i test:• Ad esempio la visibilità di tutto è public perchè i tool non
aiutano in questa direzione;
» Abbiamo alternative?
Non solo TDD
» TDD• Design emergente;• Necessita anche skill
architetturali (Pair programming);
• Sentire gli smell comporta molta esperienza;
• Posso fare refactoring: si• Chi scrive il test non è
influenzato da come ha pensato il design;
» Test First• Design upfront;• Necessita skill solo nel
design dei test;
• L’uso dei contratti evidenzia gli smell più facilmente;
• Posso fare refactoring: si• Chi scrive il test può essere
influenzato da come ha pensato il design;
Quindi... ne vale veramente la pena?
TDD e Unit Testing: mutuamente esclusivi?
» Ma se faccio TDD/Test First posso evitare di fare Unit testing?• Assolutamente no;• Lo scopo dei test è quello di coprire le possibili
casistiche di interazione tra il mondo esterno e il blocco di codice testato:• Quante casistiche abbiamo?: Int32 Add( Int32 a, Int32 b );
» Quali strumenti abbiamo: il nulla...
What’s next...
» VS2010 Good News: Code Contracts & PEX.
void SampleMethod( Int32 argument ){
CodeContracts.Requires( argument > 0 );...
}
Compile Time Warning(s): san csc.exe ;-) Possibilità di distribuire i contratti separatamente; Integrazione con PEX;
Introduzione a posterieriori in soluzione “legacy”;
» Abbiamo tonnellate di codice veramente legacy non coperto da test... Che facciamo lo testiamo?• E’ estremamente costoso perchè quasi certamente
non abbiamo codice facilmente “testabile”;• Ha senso?:• Se devo fare pesanti refactoring potrebbe avere senso
investire tempo per creare una suite di test per verificare le regressioni;• Potrebbe avere senso introdurre test ad ogni bug che
verifichiamo, sempre in ottica regressioni;
www.xedotnet.org 3327/02/2009
SI RINGRAZIA
www.xedotnet.org 3427/02/2009
» I prossimi Meeting
• .NET Micro Framework - (Virtual Meeting)• 30/4/2009 – Online ore 21:30 – MIRCO VANINI
• NetTiers & Code Generation: Rapid Application Prototyping• 8/5/2009 – Mestre, Novotel Castellana – DAVIDE SENATORE
• PROGRAMMING WITH C# 3.0• 5/6/2009 – Mestre, Novotel Castellana – ANDREA DOTTOR