SlideShare une entreprise Scribd logo
1  sur  21
Agenda
•   «Gli aforismi riassumono il mondo.» Me
•   TDD
     • What?
     • Why?
     • Where?
     • Pro/Cons
•   Feature Driven Development
•   Agile
     • XP
          • TDD
          • Pair programming
          • Pomodoro




              «Non c'è uomo che non possa bere o mangiare ma,
              sono in pochi in grado di capire che cosa abbia sapore.» Confucio
What?



Test                Driven                  D




                          Development               Design




                                                    Feature




«Non esiste vento favorevole per il marinaio senza rotta.» Seneca
What?

TDD è una tecnica agile che consente di focalizzarci sulla funzionalità ed il
design, quindi sul cosa, non sul come.

Scrivere il test prima del codice è una scorciatoia molto efficace per produrre
soluzioni di qualità e un software di successo.

Se «nella vita è importante il percorso e non la meta» nel caso delle attività
produttive è vero il contrario, quindi «il fine giustifica i mezzi», nella sua
accezione più positiva, è la filosofia con cui questa metodologia di sviluppo
si è imposta come alternativa negli ultimi anni.




             «Cominciate col fare ciò che è necessario, poi ciò che è possibile.
             E all'improvviso vi sorprenderete a fare l'impossibile.» San Francesco
What?
Testing lifecycle



                                              Test




                  Refactor                                           Code




«Sono le minoranze di entusiasti a fare la storia, per poi imporla ai pigri e agli scettici.» M. Gramel
What?

1. Il «codice» non esiste, prima il test

[TestMethod]
public void CalculateDivision()
{
  var division =
     new Division (); ////The class Division not
exist
}
What?

2. Il test inizialmente deve fallire

[TestMethod]                                public class Division
public void DivideTwoPositiveNumbers()      {
{                                              public int Calculate(int a, int b)
     new Division()                           {
       .Calculate(6, 2)                          throw new NotImplementedException();
       .Should(«The division failed.»)        }
       .Be.EqualTo(3);                      }
}
What?

3. Tendenzialmente è bene supportare solo gli use-case necessari

[TestMethod]                                public class Division
public void DivideTwoPositiveNumbers()      {
{                                              public int Calculate(int a, int b)
     new Division()                           {
       .Calculate(6, 2)                          return 3;
       .Should(«The division failed.»)        }
       .Be.EqualTo(3);                      }
}
What?

4. Seguire il ciclo test-code-refectator e «no duplication»

[TestMethod]                                          public class Division
public void DivideTwoPositiveNumbers()                {
{                                                       public int Calculate(int a, int b)
     CalculateAndCheck(6, 2, 4);                        {
}                                                         return a / b;
                                                        }
[TestMethod]                                          }
public void
DivideANumberByOneMustReturnTheNumber()
{
     CalculateAndCheck(6, 1, 6);
}

private void CalculateAndCheck(int a, int b, int
expected)
{
     new Division()
       .Calculate(a, b)
       .Should(«The division failed.»)
       .Be.EqualTo(expected);
}
What?

5. Code coverage: 100% non significa codice privo di bug

[TestMethod]                                          public class Division
public void DivideANumberByZero()                     {
{                                                       public int Calculate(int a, int b)
     //This inputs breaks the code but                  {
     //the code coverage is 100%                          return a / b;
     CalculateAndCheck(6, 0, ?);                        }
}                                                     }

private void CalculateAndCheck(int a, int b, int
expected)
{
     new Division()
       .Calculate(a, b)
       .Should(«The division failed.»)
       .Be.EqualTo(expected);
}
What?

6. Bug fixing: bug - test - fix

[TestMethod]                                          public class Division
[ExpectedException(typeof(DivideByZeroException)      {
]                                                       public double Calculate(int a, int b)
public void                                             {
DivideANumberByZeroThrowsException()                      return a / b;
{                                                       }
     //This inputs breaks the code but                }
     //the code coverage is 100%
     CalculateAndCheck(6, 0, double.NaN);
}

private void CalculateAndCheck(int a, int b, double
expected)
{
     new Division()
       .Calculate(a, b)
       .Should(«The division failed.»)
       .Be.EqualTo(expected);
}
What?

Il codice di test ha pari dignità del codice applicativo. Il codice di test è codice
applicativo.
Va manutenuto, il refactoring è lo strumento da utilizzare.

La duplicazione è il male assoluto: never duplicate.

Ancora più importante del KISS («Keep it short and simple», in originale «Keep
it Simple, Stupid!») principle.

Se il codice è complesso ma centralizzato, il refactoring è applicabile in modo
piuttosto efficiente.

Se il codice, anche semplice, è duplicato in molti punti, correggerlo e
migliorarlo diventa un’impresa titanica!

Il refactoring è l’attività sul codice che ne mantiene invariato l’aspetto
funzionale migliorando la manutenibilità. E’ fondamentale seguire il ciclo sopra
descritto e continuare a semplificiare e «spezzare» secondo il Single Point of
Why?

La complessità del sistema è maggiore della somma della complessità delle
singole parti.

TDD consente di continuare a «spezzare» le singole parti, renderle testabili e
quindi maggiormente affidabili.
                                      Z la formica




                          «Siiiiii... la palla!.» da «Z la formica»
Why?

I «test» sono un piacevole side effect di TDD, ma non sono il goal principale.

La robustezza dell’applicazione è data da molti fattori, tra i quali
un’architettura semplice.

Scrivere meno codice possibile. Meno codice, statisticamente meno bug.

Aumentare la leggibilità: usare la tecnica di refactoring «extract method» a
manetta!




           «La semplicità è la forma della vera grandezza.» Francesco De Sanctis
Why?

//<ironic>Comments are unuseful!</ironic>

var value = "The fox is near the window.";

var characterList = new List<char>();

foreach (var c in value)
{
  if (c< ‘0’ || c> ‘9’)
  {
     characterList.Add(char.ToUpper(c));
  }
}

characterList.Reverse();

var ret = new string(characterList.ToArray());



Raise your hand when you understand what the code does.
Why?

MakeMethodsNotWar();

RemoveNumbersMakeToUpperAndReverse(«"The fox is near the window.“);




Raise your hand when you understand what the code does.
Where?

• Unit test
• Integration test

Gli unit test consentono di definire il design di «unit» di codice, cioè classi.
Hanno la caratteristica di non usare risorse lente (IO, DB, servizi, device),
devono essere eseguiti costantemente, ad ogni modifica del codice e nel modo
più veloce possibile. Devono essere istantanei.
Where?

• Unit test
• Integration test

Gli integration test sono particolari tipi di unit test che lavorano su classi di
produzione, verificando la correttezza di parti dell’applicazione che saranno
«davvero in gioco».

Sono complessi da manutenere e scrivere, ma sono le vere basi del software.

- Benchmark
- Long times operations
- components orchestration
Where?

Where? Check again the session title!

Fight the «we are different syndrome»!

Alcuni esempi «estremi» a cui applicare TDD:
- gaming: BomberMan
- vision: Motion Detector
- hardware interaction: SerialPort
- TFS and MSBuild: ContinuosIntegration




              «Aspira a migliorare il mondo per migliorare davvero te stesso.» Me
Feature                Driven            Development




«Nulla è più facile che illudersi. Perché l'uomo crede vero ciò che desidera.» Demostene
Ringraziamenti



A mia moglie, che sopporta «EveryThing»




Ad                  per avermi permesso di ultimare le slide
To be continued...


More slides have to come on this TDD session.

Contenu connexe

Tendances

Java Unit Testing - In container and database testing
Java Unit Testing - In container and database testingJava Unit Testing - In container and database testing
Java Unit Testing - In container and database testingfgianneschi
 
Lezione 3: Sviluppo in Extreme Programming
Lezione 3: Sviluppo in Extreme ProgrammingLezione 3: Sviluppo in Extreme Programming
Lezione 3: Sviluppo in Extreme ProgrammingAndrea Della Corte
 
A brief intro to TDD for a JUG-TAA event
A brief intro to TDD for a JUG-TAA eventA brief intro to TDD for a JUG-TAA event
A brief intro to TDD for a JUG-TAA eventPietro Di Bello
 
Design pattern template method
Design pattern template methodDesign pattern template method
Design pattern template methodNelson Firmani
 
Test double - un'introduzione (PHP)
Test double - un'introduzione (PHP)Test double - un'introduzione (PHP)
Test double - un'introduzione (PHP)Carmelantonio Zolfo
 
Lezione 6b: Design Pattern Strutturali
Lezione 6b: Design Pattern StrutturaliLezione 6b: Design Pattern Strutturali
Lezione 6b: Design Pattern StrutturaliAndrea Della Corte
 

Tendances (7)

Java Unit Testing - In container and database testing
Java Unit Testing - In container and database testingJava Unit Testing - In container and database testing
Java Unit Testing - In container and database testing
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
Lezione 3: Sviluppo in Extreme Programming
Lezione 3: Sviluppo in Extreme ProgrammingLezione 3: Sviluppo in Extreme Programming
Lezione 3: Sviluppo in Extreme Programming
 
A brief intro to TDD for a JUG-TAA event
A brief intro to TDD for a JUG-TAA eventA brief intro to TDD for a JUG-TAA event
A brief intro to TDD for a JUG-TAA event
 
Design pattern template method
Design pattern template methodDesign pattern template method
Design pattern template method
 
Test double - un'introduzione (PHP)
Test double - un'introduzione (PHP)Test double - un'introduzione (PHP)
Test double - un'introduzione (PHP)
 
Lezione 6b: Design Pattern Strutturali
Lezione 6b: Design Pattern StrutturaliLezione 6b: Design Pattern Strutturali
Lezione 6b: Design Pattern Strutturali
 

En vedette

4c過度儀式與社群
4c過度儀式與社群4c過度儀式與社群
4c過度儀式與社群Bo Hong
 
二、特納儀式理論中的象徵符號1
二、特納儀式理論中的象徵符號1二、特納儀式理論中的象徵符號1
二、特納儀式理論中的象徵符號1Bo Hong
 
How to think like a startup
How to think like a startupHow to think like a startup
How to think like a startupLoic Le Meur
 
Teaching Students with Emojis, Emoticons, & Textspeak
Teaching Students with Emojis, Emoticons, & TextspeakTeaching Students with Emojis, Emoticons, & Textspeak
Teaching Students with Emojis, Emoticons, & TextspeakShelly Sanchez Terrell
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerLuminary Labs
 

En vedette (6)

4c過度儀式與社群
4c過度儀式與社群4c過度儀式與社群
4c過度儀式與社群
 
二、特納儀式理論中的象徵符號1
二、特納儀式理論中的象徵符號1二、特納儀式理論中的象徵符號1
二、特納儀式理論中的象徵符號1
 
Inaugural Addresses
Inaugural AddressesInaugural Addresses
Inaugural Addresses
 
How to think like a startup
How to think like a startupHow to think like a startup
How to think like a startup
 
Teaching Students with Emojis, Emoticons, & Textspeak
Teaching Students with Emojis, Emoticons, & TextspeakTeaching Students with Emojis, Emoticons, & Textspeak
Teaching Students with Emojis, Emoticons, & Textspeak
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI Explainer
 

Similaire à Tdd.Every.Where.21012012

Workshop Test Drive Development
Workshop Test Drive DevelopmentWorkshop Test Drive Development
Workshop Test Drive DevelopmentCommit University
 
Migrazione dei meccanismi di workflow di un sistema informativo assicurativo ...
Migrazione dei meccanismi di workflow di un sistema informativo assicurativo ...Migrazione dei meccanismi di workflow di un sistema informativo assicurativo ...
Migrazione dei meccanismi di workflow di un sistema informativo assicurativo ...Donato Clun
 
Junit tutorial
Junit tutorialJunit tutorial
Junit tutorialfdesimone
 
AntiPatterns: i vizi del programmatore
AntiPatterns: i vizi del programmatoreAntiPatterns: i vizi del programmatore
AntiPatterns: i vizi del programmatoreManuel Scapolan
 
Fe05 test drivenjavascriptdevelopment
Fe05   test drivenjavascriptdevelopmentFe05   test drivenjavascriptdevelopment
Fe05 test drivenjavascriptdevelopmentDotNetCampus
 
Una fugace occhiata al Test Driven Development (2006)
Una fugace occhiata al Test Driven Development  (2006)Una fugace occhiata al Test Driven Development  (2006)
Una fugace occhiata al Test Driven Development (2006)Roberto Bettazzoni
 
The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...
The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...
The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...Davide Cerbo
 
Presentazione della Tesi di Laurea Specialistica : STRUMENTI PER LA GENERAZIO...
Presentazione della Tesi di Laurea Specialistica : STRUMENTI PER LA GENERAZIO...Presentazione della Tesi di Laurea Specialistica : STRUMENTI PER LA GENERAZIO...
Presentazione della Tesi di Laurea Specialistica : STRUMENTI PER LA GENERAZIO...Boymix81
 
Android Test Driven Development
Android Test Driven DevelopmentAndroid Test Driven Development
Android Test Driven Developmentsazilla
 
Android Test Driven Development
Android Test Driven DevelopmentAndroid Test Driven Development
Android Test Driven Developmentsazilla
 
Java Symbolic Regression - Machine Learining
Java Symbolic Regression - Machine LeariningJava Symbolic Regression - Machine Learining
Java Symbolic Regression - Machine LeariningAndrea Ciccotta
 
DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...
DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...
DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...Alessandro Alpi
 
Layered Expression Trees feat. CQRS
Layered Expression Trees feat. CQRSLayered Expression Trees feat. CQRS
Layered Expression Trees feat. CQRSAndrea Saltarello
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java BaseK-Tech Formazione
 
Test Driven Development @ Xe.Net
Test Driven Development @ Xe.NetTest Driven Development @ Xe.Net
Test Driven Development @ Xe.NetMauro Servienti
 

Similaire à Tdd.Every.Where.21012012 (20)

Workshop Test Drive Development
Workshop Test Drive DevelopmentWorkshop Test Drive Development
Workshop Test Drive Development
 
Migrazione dei meccanismi di workflow di un sistema informativo assicurativo ...
Migrazione dei meccanismi di workflow di un sistema informativo assicurativo ...Migrazione dei meccanismi di workflow di un sistema informativo assicurativo ...
Migrazione dei meccanismi di workflow di un sistema informativo assicurativo ...
 
Junit tutorial
Junit tutorialJunit tutorial
Junit tutorial
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
AntiPatterns: i vizi del programmatore
AntiPatterns: i vizi del programmatoreAntiPatterns: i vizi del programmatore
AntiPatterns: i vizi del programmatore
 
Workshop: Introduzione ad TDD
Workshop: Introduzione ad TDDWorkshop: Introduzione ad TDD
Workshop: Introduzione ad TDD
 
Fe05 test drivenjavascriptdevelopment
Fe05   test drivenjavascriptdevelopmentFe05   test drivenjavascriptdevelopment
Fe05 test drivenjavascriptdevelopment
 
Una fugace occhiata al Test Driven Development (2006)
Una fugace occhiata al Test Driven Development  (2006)Una fugace occhiata al Test Driven Development  (2006)
Una fugace occhiata al Test Driven Development (2006)
 
The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...
The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...
The Hitchhiker's Guide to testable code: semplici regole per scrivere codice ...
 
Presentazione della Tesi di Laurea Specialistica : STRUMENTI PER LA GENERAZIO...
Presentazione della Tesi di Laurea Specialistica : STRUMENTI PER LA GENERAZIO...Presentazione della Tesi di Laurea Specialistica : STRUMENTI PER LA GENERAZIO...
Presentazione della Tesi di Laurea Specialistica : STRUMENTI PER LA GENERAZIO...
 
Android Test Driven Development
Android Test Driven DevelopmentAndroid Test Driven Development
Android Test Driven Development
 
Android Test Driven Development
Android Test Driven DevelopmentAndroid Test Driven Development
Android Test Driven Development
 
Java Symbolic Regression - Machine Learining
Java Symbolic Regression - Machine LeariningJava Symbolic Regression - Machine Learining
Java Symbolic Regression - Machine Learining
 
Software Testing e TDD
Software Testing e TDDSoftware Testing e TDD
Software Testing e TDD
 
Vb.Net
Vb.NetVb.Net
Vb.Net
 
DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...
DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...
DevOpsHeroes 2016 - Realizzare Continouous Integration con SQL Server e Visua...
 
Layered Expression Trees feat. CQRS
Layered Expression Trees feat. CQRSLayered Expression Trees feat. CQRS
Layered Expression Trees feat. CQRS
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
 
Test Driven Development @ Xe.Net
Test Driven Development @ Xe.NetTest Driven Development @ Xe.Net
Test Driven Development @ Xe.Net
 
Java lezione1
Java lezione1Java lezione1
Java lezione1
 

Tdd.Every.Where.21012012

  • 1. Agenda • «Gli aforismi riassumono il mondo.» Me • TDD • What? • Why? • Where? • Pro/Cons • Feature Driven Development • Agile • XP • TDD • Pair programming • Pomodoro «Non c'è uomo che non possa bere o mangiare ma, sono in pochi in grado di capire che cosa abbia sapore.» Confucio
  • 2. What? Test Driven D Development Design Feature «Non esiste vento favorevole per il marinaio senza rotta.» Seneca
  • 3. What? TDD è una tecnica agile che consente di focalizzarci sulla funzionalità ed il design, quindi sul cosa, non sul come. Scrivere il test prima del codice è una scorciatoia molto efficace per produrre soluzioni di qualità e un software di successo. Se «nella vita è importante il percorso e non la meta» nel caso delle attività produttive è vero il contrario, quindi «il fine giustifica i mezzi», nella sua accezione più positiva, è la filosofia con cui questa metodologia di sviluppo si è imposta come alternativa negli ultimi anni. «Cominciate col fare ciò che è necessario, poi ciò che è possibile. E all'improvviso vi sorprenderete a fare l'impossibile.» San Francesco
  • 4. What? Testing lifecycle Test Refactor Code «Sono le minoranze di entusiasti a fare la storia, per poi imporla ai pigri e agli scettici.» M. Gramel
  • 5. What? 1. Il «codice» non esiste, prima il test [TestMethod] public void CalculateDivision() { var division = new Division (); ////The class Division not exist }
  • 6. What? 2. Il test inizialmente deve fallire [TestMethod] public class Division public void DivideTwoPositiveNumbers() { { public int Calculate(int a, int b) new Division() { .Calculate(6, 2) throw new NotImplementedException(); .Should(«The division failed.») } .Be.EqualTo(3); } }
  • 7. What? 3. Tendenzialmente è bene supportare solo gli use-case necessari [TestMethod] public class Division public void DivideTwoPositiveNumbers() { { public int Calculate(int a, int b) new Division() { .Calculate(6, 2) return 3; .Should(«The division failed.») } .Be.EqualTo(3); } }
  • 8. What? 4. Seguire il ciclo test-code-refectator e «no duplication» [TestMethod] public class Division public void DivideTwoPositiveNumbers() { { public int Calculate(int a, int b) CalculateAndCheck(6, 2, 4); { } return a / b; } [TestMethod] } public void DivideANumberByOneMustReturnTheNumber() { CalculateAndCheck(6, 1, 6); } private void CalculateAndCheck(int a, int b, int expected) { new Division() .Calculate(a, b) .Should(«The division failed.») .Be.EqualTo(expected); }
  • 9. What? 5. Code coverage: 100% non significa codice privo di bug [TestMethod] public class Division public void DivideANumberByZero() { { public int Calculate(int a, int b) //This inputs breaks the code but { //the code coverage is 100% return a / b; CalculateAndCheck(6, 0, ?); } } } private void CalculateAndCheck(int a, int b, int expected) { new Division() .Calculate(a, b) .Should(«The division failed.») .Be.EqualTo(expected); }
  • 10. What? 6. Bug fixing: bug - test - fix [TestMethod] public class Division [ExpectedException(typeof(DivideByZeroException) { ] public double Calculate(int a, int b) public void { DivideANumberByZeroThrowsException() return a / b; { } //This inputs breaks the code but } //the code coverage is 100% CalculateAndCheck(6, 0, double.NaN); } private void CalculateAndCheck(int a, int b, double expected) { new Division() .Calculate(a, b) .Should(«The division failed.») .Be.EqualTo(expected); }
  • 11. What? Il codice di test ha pari dignità del codice applicativo. Il codice di test è codice applicativo. Va manutenuto, il refactoring è lo strumento da utilizzare. La duplicazione è il male assoluto: never duplicate. Ancora più importante del KISS («Keep it short and simple», in originale «Keep it Simple, Stupid!») principle. Se il codice è complesso ma centralizzato, il refactoring è applicabile in modo piuttosto efficiente. Se il codice, anche semplice, è duplicato in molti punti, correggerlo e migliorarlo diventa un’impresa titanica! Il refactoring è l’attività sul codice che ne mantiene invariato l’aspetto funzionale migliorando la manutenibilità. E’ fondamentale seguire il ciclo sopra descritto e continuare a semplificiare e «spezzare» secondo il Single Point of
  • 12. Why? La complessità del sistema è maggiore della somma della complessità delle singole parti. TDD consente di continuare a «spezzare» le singole parti, renderle testabili e quindi maggiormente affidabili. Z la formica «Siiiiii... la palla!.» da «Z la formica»
  • 13. Why? I «test» sono un piacevole side effect di TDD, ma non sono il goal principale. La robustezza dell’applicazione è data da molti fattori, tra i quali un’architettura semplice. Scrivere meno codice possibile. Meno codice, statisticamente meno bug. Aumentare la leggibilità: usare la tecnica di refactoring «extract method» a manetta! «La semplicità è la forma della vera grandezza.» Francesco De Sanctis
  • 14. Why? //<ironic>Comments are unuseful!</ironic> var value = "The fox is near the window."; var characterList = new List<char>(); foreach (var c in value) { if (c< ‘0’ || c> ‘9’) { characterList.Add(char.ToUpper(c)); } } characterList.Reverse(); var ret = new string(characterList.ToArray()); Raise your hand when you understand what the code does.
  • 15. Why? MakeMethodsNotWar(); RemoveNumbersMakeToUpperAndReverse(«"The fox is near the window.“); Raise your hand when you understand what the code does.
  • 16. Where? • Unit test • Integration test Gli unit test consentono di definire il design di «unit» di codice, cioè classi. Hanno la caratteristica di non usare risorse lente (IO, DB, servizi, device), devono essere eseguiti costantemente, ad ogni modifica del codice e nel modo più veloce possibile. Devono essere istantanei.
  • 17. Where? • Unit test • Integration test Gli integration test sono particolari tipi di unit test che lavorano su classi di produzione, verificando la correttezza di parti dell’applicazione che saranno «davvero in gioco». Sono complessi da manutenere e scrivere, ma sono le vere basi del software. - Benchmark - Long times operations - components orchestration
  • 18. Where? Where? Check again the session title! Fight the «we are different syndrome»! Alcuni esempi «estremi» a cui applicare TDD: - gaming: BomberMan - vision: Motion Detector - hardware interaction: SerialPort - TFS and MSBuild: ContinuosIntegration «Aspira a migliorare il mondo per migliorare davvero te stesso.» Me
  • 19. Feature Driven Development «Nulla è più facile che illudersi. Perché l'uomo crede vero ciò che desidera.» Demostene
  • 20. Ringraziamenti A mia moglie, che sopporta «EveryThing» Ad per avermi permesso di ultimare le slide
  • 21. To be continued... More slides have to come on this TDD session.