Share
Embed
TDD: Cose che ho imparato (negli ultimi 12 anni)
My talk at Codemotion Milano, 2016
Matteo Vaccari
November 27, 2016
Transcript
61 slides
-
UNA SFIDA: 2 Scrivi un programma che produce la lista
dei numeri da 0 a 1 milione Come lo testi? -
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 -
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? -
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 -
UNA SFIDA: 8 Scrivi un programma che produce la lista
dei numeri da 0 a 1 milione Come lo testi? -
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 -
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 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” -
How should the running of tests affect one another? Not
at all. — Kent Beck, TDD By Example 17 -
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 -
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 Questa gemma è molto ben nascosta in fondo a
pag. 125 di “TDD By Example” -
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 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")); } -
@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. -
@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 -
@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 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!!! -
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 -
NON FA REFACTORING 37 Lo smanettone Ma va là che
ne faccio fin troppo! -
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” -
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 -
UN TEST PER VOLTA 50 User story Example (== Scenario)
Test Example (== Scenario) Example (== Scenario) Test Test Child Test Child Test Child Test -
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 -
54 Object-Oriented DB-Oriented Parte dai comportamenti Parte dai dati Disaccoppia
il DB Strettamente accoppiato al DB TDD è difficile TDD: OK! -
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 The database is just a detail that you don’t
need to figure out right away. -
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? -
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