Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

    View Slide

  2. UNA SFIDA:
    2
    Scrivi un programma che produce la lista dei numeri da 0 a 1 milione
    Come lo testi?

    View Slide

  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

    View Slide

  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?

    View Slide

  5. 1. COME INIZIARE
    5

    View Slide

  6. 6

    View Slide

  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

    View Slide

  8. UNA SFIDA:
    8
    Scrivi un programma che produce la lista dei numeri da 0 a 1 milione
    Come lo testi?

    View Slide

  9. VARI TENTATIVI/1
    9

    View Slide

  10. VARI TENTATIVI/2
    10

    View Slide

  11. VARI TENTATIVI/3
    11

    View Slide

  12. GENERALIZE AND SIMPLIFY
    12

    View Slide

  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

    View Slide

  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

    View Slide

  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”

    View Slide

  16. 2. ASSI ORTOGONALI
    16

    View Slide

  17. How should the running of tests affect
    one another? Not at all.
    — Kent Beck, TDD By Example
    17

    View Slide

  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

    View Slide

  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

    View Slide

  20. 20
    Questa gemma è
    molto ben nascosta in
    fondo a pag. 125 di
    “TDD By Example”

    View Slide

  21. UN ESEMPIO DI TEST NON ISOLATI
    21
    Martin Fowler, Refactoring

    View Slide

  22. 22

    View Slide

  23. 23

    View Slide

  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

    View Slide

  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"));

    }

    View Slide

  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.

    View Slide

  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

    View Slide

  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.

    View Slide

  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!!!

    View Slide

  30. TWO WAYS TO DECOMPOSE A PROBLEM
    30
    Jeff Patton, http://jpattonassociates.com/dont_know_what_i_want/
    Incremental
    Iterative

    View Slide

  31. 31

    View Slide

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

    View Slide

  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

    View Slide

  34. 3. DESIGN
    EMERGENTE
    34

    View Slide

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

    View Slide

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

    View Slide

  37. NON FA REFACTORING
    37
    Lo smanettone
    Ma va là che ne
    faccio fin
    troppo!

    View Slide

  38. FA DESIGN-DRIVEN TESTING
    38
    L’architetto
    Ho esperienza!
    So dove
    andiamo a
    parare!

    View Slide

  39. DESIGN-DRIVEN TESTING
    39
    Keith Braithwaite, TDD as if you Meant It

    View Slide

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

    View Slide

  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”

    View Slide

  42. 42
    http://wiki.c2.com/?
    DoTheSimplestThingThatCouldPossiblyWork

    View Slide

  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

    View Slide

  44. SECONDO J.B. RAINSBERGER:
    44
    Improve
    names
    Remove
    duplication
    http://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest/

    View Slide

  45. STUDIARE IL SOFTWARE DESIGN È IMPORTANTE
    45

    View Slide

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

    View Slide

  47. Che cosa faccio io in pratica?
    47

    View Slide

  48. CONDIVIDERE CON GLI STAKEHOLDER
    48

    View Slide

  49. 49
    ALLINEARSI SU UNA
    NUOVA FEATURE

    View Slide

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

    View Slide

  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

    View Slide

  52. ASPETTA DI TROVARE LE ASTRAZIONI BUONE
    52
    https://medium.com/@rdsubhas/10-modern-software-engineering-mistakes-bc67fbef4fc8

    View Slide

  53. 4. CHE FARE CON IL
    DB?
    53

    View Slide

  54. 54
    Object-Oriented DB-Oriented
    Parte dai comportamenti Parte dai dati
    Disaccoppia il DB Strettamente accoppiato al DB
    TDD è difficile
    TDD: OK!

    View Slide

  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);



    View Slide

  56. 56
    The database is
    just a detail that you don’t
    need to figure out right
    away.

    View Slide

  57. SIAMO ALLA FINE…
    57

    View Slide

  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?

    View Slide

  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

    View Slide

  60. PER IL PROSSIMO EVENTO TDD A MILANO…
    60
    Please subscribe!

    View Slide

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

    View Slide