$30 off During Our Annual Pro Sale. View Details »

TDD: Cose che ho imparato (negli ultimi 12 anni)

TDD: Cose che ho imparato (negli ultimi 12 anni)

My talk at Codemotion Milano, 2016

Matteo Vaccari

November 27, 2016
Tweet

More Decks by Matteo Vaccari

Other Decks in Technology

Transcript

  1. TDD: COSE CHE HO IMPARATO Matteo Vaccari

  2. UNA SFIDA: 2 Scrivi un programma che produce la lista

    dei numeri da 0 a 1 milione Come lo testi?
  3. 3 Autodidatta Team Orione Agile Coach ThoughtWorks Workshop Design Emergente

    Francesco Cirillo Miško Hevery Testable Code videos Kent Beck Freeman & Pryce Primo progetto XP! Primo coaching A terze parti The famous banking project The One Page Rewrite project The Panettone project Birthday Greetings Kata Open-Closed Principle Lab Simple Design in Action Lab 2006 2012 2001 2015
  4. DOMANDE ▫︎Il design emergente esiste davvero? ▫︎Il TDD richiede più

    tempo? ▫︎Come si fa con la UI? ▫︎Come si fa con il DB? ▫︎Mock sì, mock no? ▫︎Posso fidarmi di Uncle Bob? ▫︎Il TDD è morto?!? 4 Altre domande? Le tue domande?
  5. 1. COME INIZIARE 5

  6. 6

  7. TEST LIST 7 $5 + 10CHF = $10 if rate

    is 2:1 $5 * 2 = $10 1. Esempi 2. Del problema da risolvere Pag. 3 di “TDD By Example” di Kent Beck
  8. UNA SFIDA: 8 Scrivi un programma che produce la lista

    dei numeri da 0 a 1 milione Come lo testi?
  9. VARI TENTATIVI/1 9

  10. VARI TENTATIVI/2 10

  11. VARI TENTATIVI/3 11

  12. GENERALIZE AND SIMPLIFY 12

  13. LA TEST LIST DEVE: 13 ▫︎Contenere esempi ▫︎Del problema da

    risolvere ▫︎Che coprano tutte le variazioni (cioè gli scenari) ▫︎Senza implicare soluzioni di design User story Example (== Scenario) Test Example (== Scenario) Example (== Scenario) Test Test Child Test Child Test Child Test
  14. DA QUALE TEST PARTIRE? A. Da un test sulla UI?

    (outside-in) B. Da un test sulla logica di dominio? (inside-out) C. ? 14
  15. 15 TDD By Example, p. 133 Which test should you

    pick next from the list? Pick a test that ▪ will teach you something ▪ you are confident you can implement “From known to unknown”
  16. 2. ASSI ORTOGONALI 16

  17. How should the running of tests affect one another? Not

    at all. — Kent Beck, TDD By Example 17
  18. If I had one test broken, I wanted one problem.

    If I had two tests broken, I wanted two problems. — Kent Beck, TDD By Example 18
  19. A second implication of isolated tests is that you have

    to work, sometimes work hard, to break your problem into little orthogonal dimensions. — Kent Beck, TDD By Example 19
  20. 20 Questa gemma è molto ben nascosta in fondo a

    pag. 125 di “TDD By Example”
  21. UN ESEMPIO DI TEST NON ISOLATI 21 Martin Fowler, Refactoring

  22. 22

  23. 23

  24. UN ALTRO ESEMPIO DI TEST NON ISOLATI 24 Password-strength checker

    In order to be an acceptable password, a string must: * Have a length greater than 7 characters. * Contain at least one alphabetic character. * Contain at least one digit. Rob Myers, on the TDD mailing list
  25. 25 Password-strength checker In order to be an acceptable password,

    a string must: * Have a length greater than 7 characters. * Contain at least one alphabetic character. * Contain at least one digit. @Test
 public void passwordTooShort() {
 assertEqual(false, isValidPassword(""));
 assertEqual(false, isValidPassword("aaa"));
 assertEqual(false, isValidPassword("aaaaaaa"));
 }
 
 @Test
 public void passwordIsGood() {
 assertEqual(true, isValidPassword("abcdefgh"));
 }
  26. @Test
 public void passwordTooShort() {
 assertEqual(false, isValidPassword(""));
 assertEqual(false, isValidPassword("aaa"));
 assertEqual(false,

    isValidPassword("aaaaaaa"));
 }
 
 @Test
 public void passwordIsGood() {
 assertEqual(true, isValidPassword("abcdefgh"));
 }
 
 @Test
 public void passwordContainsNoAlpha() {
 assertEqual(false, isValidPassword("12345678"));
 }
 26 Password-strength checker In order to be an acceptable password, a string must: * Have a length greater than 7 characters. * Contain at least one alphabetic character. * Contain at least one digit.
  27. @Test
 public void passwordTooShort() {
 assertEqual(false, isValidPassword(""));
 assertEqual(false, isValidPassword("aaa"));
 assertEqual(false,

    isValidPassword("aaaaaaa"));
 }
 
 @Test
 public void passwordIsGood() {
 assertEqual(true, isValidPassword("abcdefgh"));
 }
 
 @Test
 public void passwordContainsNoAlpha() {
 assertEqual(false, isValidPassword("12345678"));
 }
 
 @Test
 public void passwordContainsNoDigit() {
 assertEqual(false, isValidPassword("abcdefgh"));
 }
 27 Password-strength checker In order to be an acceptable password, a string must: * Have a length greater than 7 characters. * Contain at least one alphabetic character. * Contain at least one digit. Ora fallisce Ora sono invalidi per due motivi
  28. @Test
 public void passwordTooShort() {
 assertEqual(false, isValidPassword(""));
 assertEqual(false, isValidPassword("7aa"));
 assertEqual(false,

    isValidPassword("9aaaaaa"));
 }
 
 @Test
 public void passwordIsGood() {
 assertEqual(true, isValidPassword("1234abcd"));
 }
 
 @Test
 public void passwordContainsNoAlpha() {
 assertEqual(false, isValidPassword("12345678"));
 }
 
 @Test
 public void passwordContainsNoDigit() {
 assertEqual(false, isValidPassword("abcdefgh"));
 }
 28 Password-strength checker In order to be an acceptable password, a string must: * Have a length greater than 7 characters. * Contain at least one alphabetic character. * Contain at least one digit.
  29. 29 Password-strength checker In order to be an acceptable password,

    a string must: * Have a length greater than 7 * Contain at least one alphabetic * Contain at least one digit. * Contain at least one uppercase * Contain at least one lowercase @Test
 public void passwordTooShort() {
 assertEqual(false, isValidPassword(""));
 assertEqual(false, isValidPassword("7aa"));
 assertEqual(false, isValidPassword("9aaaaaa"));
 }
 
 @Test
 public void passwordIsGood() {
 assertEqual(true, isValidPassword("1234abcd"));
 }
 
 @Test
 public void passwordContainsNoAlpha() {
 assertEqual(false, isValidPassword("12345678"));
 }
 
 @Test
 public void passwordContainsNoDigit() {
 assertEqual(false, isValidPassword("abcdefgh"));
 }
 Ora tutti i vecchi test sono da rivedere! New requirement!!!
  30. TWO WAYS TO DECOMPOSE A PROBLEM 30 Jeff Patton, http://jpattonassociates.com/dont_know_what_i_want/

    Incremental Iterative
  31. 31

  32. DECOMPOSE THE PROBLEM 32 Bill Wake, xp123.com/articles/slicing-functionality-alternate-paths

  33. GLI ASSI ORTOGONALI DI TETRIS ▫︎Movimento dei pezzi ▫︎Forma dei

    pezzi ▫︎Interazione dei pezzi fra di loro ▫︎Comandi del giocatore ▫︎Punteggio ▫︎Avanzamento di livello ▫︎Suoni e musica ▫︎High score e social ▫︎… 33
  34. 3. DESIGN EMERGENTE 34

  35. DUE TIPI DI PROGRAMMATORI 35 L’architetto Lo smanettone

  36. DUE TIPI DI PROGRAMMATORI 36 L’architetto Lo smanettone

  37. NON FA REFACTORING 37 Lo smanettone Ma va là che

    ne faccio fin troppo!
  38. FA DESIGN-DRIVEN TESTING 38 L’architetto Ho esperienza! So dove andiamo

    a parare!
  39. DESIGN-DRIVEN TESTING 39 Keith Braithwaite, TDD as if you Meant

    It
  40. ENTRAMBI FARANNO “BAD OOP” 40 L’architetto Lo smanettone http://geek-and-poke.com/geekandpoke/2014/11/8/frameworks

  41. TDD SECONDO KENT BECK: 1. Quickly add a test. 2.

    Run all tests and see the new one fail. 3. Make a little change. 4. Run all tests and see them all succeed. 5. Refactor to remove duplication. 41 Pag. 1 di “TDD By Example”
  42. 42 http://wiki.c2.com/? DoTheSimplestThingThatCouldPossiblyWork

  43. KENT BECK’S “FOUR RULES OF SIMPLE DESIGN” Code is simple

    enough when: 1. It passes all the tests 2. It clearly expresses intent 3. It contains no duplication 4. With the minimum number of elements 43 Da XP Explained
  44. SECONDO J.B. RAINSBERGER: 44 Improve names Remove duplication http://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest/

  45. STUDIARE IL SOFTWARE DESIGN È IMPORTANTE 45

  46. E POI, A UN CERTO PUNTO, COMINCI A CAPIRE… 46

  47. Che cosa faccio io in pratica? 47

  48. CONDIVIDERE CON GLI STAKEHOLDER 48

  49. 49 ALLINEARSI SU UNA NUOVA FEATURE

  50. UN TEST PER VOLTA 50 User story Example (== Scenario)

    Test Example (== Scenario) Example (== Scenario) Test Test Child Test Child Test Child Test
  51. UN TEST PER VOLTA 51 :Foo User input :Foo User

    input :Bar :Foo User input :Bar :Baz :Foo User input IF :Foo User input IF IF IF
  52. ASPETTA DI TROVARE LE ASTRAZIONI BUONE 52 https://medium.com/@rdsubhas/10-modern-software-engineering-mistakes-bc67fbef4fc8

  53. 4. CHE FARE CON IL DB? 53

  54. 54 Object-Oriented DB-Oriented Parte dai comportamenti Parte dai dati Disaccoppia

    il DB Strettamente accoppiato al DB TDD è difficile TDD: OK!
  55. THE “SANDWICH” PATTERN 55 
 
 // we start the

    use case in the world of infrastructure
 CounterRepository repository = ...;
 Counter counter = repository.findCounter(id);
 
 // here we enter the world of pure logic
 counter.increment();
 
 // here we return to the world of infrastructure
 dao.save(counter);
 
 

  56. 56 The database is just a detail that you don’t

    need to figure out right away.
  57. SIAMO ALLA FINE… 57

  58. HO RISPOSTO? ▫︎Il design emergente esiste davvero? ▫︎Il TDD richiede

    più tempo? ▫︎Come si fa con la UI? ▫︎Come si fa con il DB? ▫︎Mock sì, mock no? ▫︎Posso fidarmi di Uncle Bob? ▫︎Il TDD è morto?!? 58 Altre domande? Le tue domande?
  59. WHERE TO FIND MORE HELP ▫︎Milano XPUG ▫︎Rileggi “TDD By

    Example” una volta all’anno ▫︎J.B. Rainsberger’s video training ▫︎Growing Object-Oriented Software book and mailing list ▫︎TDD Mailing list on Yahoo 59
  60. PER IL PROSSIMO EVENTO TDD A MILANO… 60 Please subscribe!

  61. matteo.vaccari.name/blog twitter.com/xpmatteo thoughtworks.com GRAZIE Assumiamo! matteo.vaccari.name