際際滷

際際滷Share a Scribd company logo
Una fugace occhiata al
Test Driven Development
Roberto Bettazzoni
roberto@bettazzoni.it

http://creativecommons.org/licenses/by-sa/3.0/
1
Cosa 竪 il TDD?

2
Cosa 竪 il TDD?
Una pratica agile.

3
Pratiche agili ... cosa sono?

Pratiche agili ... cosa sono?
Sono le pratiche utilizzate nelle
metodologie agili.

4
Metodologie agili ... cosa sono?

Metodologie agili ... cosa sono?
Sono le metodologie basate sui valori
dell'Agile Manifesto

5
Il Manifesto dell'Alleanza Agile
Stiamo portando alla luce metodi migliori di sviluppare software
facendolo in prima persona e aiutando altri a farlo. Attraverso
questo tipo di lavoro siamo giunti ai seguenti valori:
Persone e interazioni pi湛 che processi e tools
Software che funziona pi湛 che una documentazione esaustiva
Collaborazione con il cliente pi湛 che negoziazione contrattuale
Rispondere al cambiamento pi湛 che seguire un piano prestabilito
Cio竪, mentre c'竪 un valore nelle voci sulla destra,
attribuiamo un valore maggiore a quelle sulla sinistra.
Kent Beck, Mike Beedle, Arie van Bennekum, Alistair Cockburn, Ward Cunningham, Martin Fowler, James Grenning, Jim Highsmith,
Andrew Hunt, Ron Jeffries, Jon Kern, Brian Marick, Robert C. Martin, Steve Mellor, Ken Schwaber, Jeff Sutherland, Dave Thomas.
息 2001, gli autori sopra citati. Questa dichiarazione pu嘆 essere copiata in ogni forma, ma solo nella sua interezza, compresa la presentenota.

6
Metodologie e pratiche


Pratica



Metodologia

Modalit per il
conseguimento di uno
scopo. Spesso 竪
formulata in sequenze di
passi.

Insieme di pratiche legate
tra loro da una visione
filosofica d'insieme.

Es: TDD

Es: Scrum

Queste definizioni, nella loro accezione generica, sono fonte di numerose discussioni.
Devono essere considerate come semplificazione per i nostri scopi.
7
Metodologie Agili

Rispondere al cambiamento
pi湛 che
seguire un piano prestabilito
Cambia il metodo di approccio al problema.

8
Metodologie Agili
Le metodologie 'storiche' hanno un
approccio

PREDITTIVO
(elaborare un piano e seguirlo)
Le metodologie agili hanno un approccio

ADATTATIVO
(rispondere al cambiamento)
9
Basi del TDD

Un linguaggio di programmazione
Un sistema di Test (unit test)
Il Refactoring

10
Refactoring

Processo di modifica evolutiva di un
sistema software in modo da non
modificarne il comportamento esterno
migliorandone la sua struttura

11
Refactoring



modifica il codice in piccoli passi



migliora continuamente il design



il codice diventa 束parlante損



richiede disciplina



la pratica rende perfetti



richiede un buon 束fiuto損

12
Refactoring
Alcune 束puzze損 comuni

...ed alcune soluzioni

1. codice duplicato
2. metodi/classi lunghe
3. lunghe liste di parametri
4. cambiamenti divergenti
5. shotgun surgery
6. codice 束invidioso損
7. liste di switch/if
8. generalizzazione
speculativa: 束astronauti損
9. commenti!

1. estrai la parte duplicata
2. separa le competenze
3. introduci/estrai oggetti
4. separa le competenze
5. riunire la responsabilit
6. muovi/estrai metodo
7. polimorfismo
8. canc, canc, canc, canc,
canc, canc, canc, canc
9. nascosto dal deodorante!
13
Test Driven Development (TDD)
Nei processi di sviluppo software tradizionali il
collaudo si fa alla fine...
Nella realt il collaudo non viene mai fatto :(

Perch竪?
+ stress => - test
- test => + stress
14
Test Driven Development (TDD)
In TDD i test guidano lo sviluppo!
Implementa

Scrivi i test per una
nuova funzionalit

Rifattorizza
il codice

Commit

15
Test Driven Development (TDD)
Per un buon TDD:


Pensa ai test prima di pensare l'implementazione



Una 束barra rossa損 竪 meglio di uno schermo bianco



I test devono essere semplici e leggibili



I test devono essere isolati



I test devono essere veloci e lanciati spesso





Verifica prima il risultato atteso, verifica i casi limite,
verifica le eccezioni
Rifattorizza sia l'implementazione che i test
16
Test Driven Development (TDD)
TDD significa anche 束Test Driven Design損








Permette di definire l'interfaccia degli oggetti prima
di buttarsi sull'implementazione
Permette di concentrarsi sul comportamento
dell'oggetto
Permette di rifattorizzare il codice con maggiore
confidenza
Porta alla realizzazione di architetture con basso
accoppiamento

17
Test Driven Development (TDD)
Con TDD posso anche...


Documentare l'utilizzo dei miei componenti
attraverso i test



Evitare la regressione dei bug



Isolare codice legacy



Dormire un po' pi湛 tranquillo la sera dopo il rilascio

18
Test Driven Development (TDD)
TDD non 竪 Unit Testing


...ma sono ottimi amici :)

Come testare le interfacce utente?


Utilizzando tool ad-hoc



Rimuovendo la logica dalle interfacce

Come testare liberandosi da risorse esterne?


Mock

TDD pu嘆 creare dipendenza! :)
19
Test Driven Development (TDD)
Strumenti:


*Unit: JUnit, PyUnit, NUnit, CPPUnit, PHPUnit, ...



DBUnit, SQLUnit, PL/SQL Unit, ...



EasyMock, Moquer, MockEJB, ...



Selenium, HttpUnit, Jmeter, ...



Fit, Fitnesse, ...

...forse pure troppi

20
Test Driven Development (TDD)

DOMANDE?

21
Esempi di TDD
(Test Driven Development)

Roberto Bettazzoni
roberto@bettazzoni.it

http://creativecommons.org/licenses/by-sa/3.0/
22
Primo Esempio di TDD

Prima User Story.
Una funzione XML-RPC che, dato il nome di un
file presente sul server, ne ritorni il contenuto
Primo Esempio di TDD
Acceptance test.
#!/usr/bin/env python
from xmlrpclib import ServerProxy
srv = ServerProxy('http://localhost:8000')
f = open(__file__, "rt")
try:
assert srv.load(__file__) == f.read()
finally:
f.close()
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)
Una fugace occhiata al Test Driven Development  (2006)
Una fugace occhiata al Test Driven Development  (2006)
test.py
import unittest, os
from load import *
class Test(unittest.TestCase):
def test_load_file_not_exists(self):
assert load("") == ""
try:
os.remove("DoNotExist")
except OSError: pass
assert load("DoNotExist") == ""
def test_load_an_existing_file(self):
text = "I'm a lumberjack and I'm okay"
fname = "TEST.tmp"
f = open(fname, "wt")
f.write(text)
f.close()
assert load(fname) == text
os.remove(fname)
if __name__ == '__main__':
unittest.main()
load.py

def load(name):
try:
f = open(name, "rt")
try:
return f.read()
finally:
f.close()
except IOError:
return ""
test.py
import unittest, os, pyprocess, xmlrpclib
from load import *
def createFile(fname, text):
f = open(fname, "wt")
f.write(text)
f.close()
class Test(unittest.TestCase):
def test_load_file_not_exists(self):
def test_load_an_existing_file(self):

...
...

class TestServer(unittest.TestCase):
def test(self):
proc = pyprocess.PyProcess("load.py")
proc.start()
createFile("other", "text")
try:
rpc = xmlrpclib.ServerProxy('http://localhost:8000')
assert rpc.load("other") == "text"
finally:
proc.kill()
os.remove("other")
load.py
import os, SimpleXMLRPCServer
def load(name):
try:
f = open(name, "rt")
try:
return f.read()
finally:
f.close()
except IOError:
return ""
if __name__ == '__main__':
srv = SimpleXMLRPCServer.SimpleXMLRPCServer(("",8000))
srv.register_function(load)
srv.serve_forever()
Primo Esempio di TDD

Eseguendo il file load.py
il test di accettazione gira senza errori.
End of Job (?)

More Related Content

Una fugace occhiata al Test Driven Development (2006)

  • 1. Una fugace occhiata al Test Driven Development Roberto Bettazzoni roberto@bettazzoni.it http://creativecommons.org/licenses/by-sa/3.0/ 1
  • 2. Cosa 竪 il TDD? 2
  • 3. Cosa 竪 il TDD? Una pratica agile. 3
  • 4. Pratiche agili ... cosa sono? Pratiche agili ... cosa sono? Sono le pratiche utilizzate nelle metodologie agili. 4
  • 5. Metodologie agili ... cosa sono? Metodologie agili ... cosa sono? Sono le metodologie basate sui valori dell'Agile Manifesto 5
  • 6. Il Manifesto dell'Alleanza Agile Stiamo portando alla luce metodi migliori di sviluppare software facendolo in prima persona e aiutando altri a farlo. Attraverso questo tipo di lavoro siamo giunti ai seguenti valori: Persone e interazioni pi湛 che processi e tools Software che funziona pi湛 che una documentazione esaustiva Collaborazione con il cliente pi湛 che negoziazione contrattuale Rispondere al cambiamento pi湛 che seguire un piano prestabilito Cio竪, mentre c'竪 un valore nelle voci sulla destra, attribuiamo un valore maggiore a quelle sulla sinistra. Kent Beck, Mike Beedle, Arie van Bennekum, Alistair Cockburn, Ward Cunningham, Martin Fowler, James Grenning, Jim Highsmith, Andrew Hunt, Ron Jeffries, Jon Kern, Brian Marick, Robert C. Martin, Steve Mellor, Ken Schwaber, Jeff Sutherland, Dave Thomas. 息 2001, gli autori sopra citati. Questa dichiarazione pu嘆 essere copiata in ogni forma, ma solo nella sua interezza, compresa la presentenota. 6
  • 7. Metodologie e pratiche Pratica Metodologia Modalit per il conseguimento di uno scopo. Spesso 竪 formulata in sequenze di passi. Insieme di pratiche legate tra loro da una visione filosofica d'insieme. Es: TDD Es: Scrum Queste definizioni, nella loro accezione generica, sono fonte di numerose discussioni. Devono essere considerate come semplificazione per i nostri scopi. 7
  • 8. Metodologie Agili Rispondere al cambiamento pi湛 che seguire un piano prestabilito Cambia il metodo di approccio al problema. 8
  • 9. Metodologie Agili Le metodologie 'storiche' hanno un approccio PREDITTIVO (elaborare un piano e seguirlo) Le metodologie agili hanno un approccio ADATTATIVO (rispondere al cambiamento) 9
  • 10. Basi del TDD Un linguaggio di programmazione Un sistema di Test (unit test) Il Refactoring 10
  • 11. Refactoring Processo di modifica evolutiva di un sistema software in modo da non modificarne il comportamento esterno migliorandone la sua struttura 11
  • 12. Refactoring modifica il codice in piccoli passi migliora continuamente il design il codice diventa 束parlante損 richiede disciplina la pratica rende perfetti richiede un buon 束fiuto損 12
  • 13. Refactoring Alcune 束puzze損 comuni ...ed alcune soluzioni 1. codice duplicato 2. metodi/classi lunghe 3. lunghe liste di parametri 4. cambiamenti divergenti 5. shotgun surgery 6. codice 束invidioso損 7. liste di switch/if 8. generalizzazione speculativa: 束astronauti損 9. commenti! 1. estrai la parte duplicata 2. separa le competenze 3. introduci/estrai oggetti 4. separa le competenze 5. riunire la responsabilit 6. muovi/estrai metodo 7. polimorfismo 8. canc, canc, canc, canc, canc, canc, canc, canc 9. nascosto dal deodorante! 13
  • 14. Test Driven Development (TDD) Nei processi di sviluppo software tradizionali il collaudo si fa alla fine... Nella realt il collaudo non viene mai fatto :( Perch竪? + stress => - test - test => + stress 14
  • 15. Test Driven Development (TDD) In TDD i test guidano lo sviluppo! Implementa Scrivi i test per una nuova funzionalit Rifattorizza il codice Commit 15
  • 16. Test Driven Development (TDD) Per un buon TDD: Pensa ai test prima di pensare l'implementazione Una 束barra rossa損 竪 meglio di uno schermo bianco I test devono essere semplici e leggibili I test devono essere isolati I test devono essere veloci e lanciati spesso Verifica prima il risultato atteso, verifica i casi limite, verifica le eccezioni Rifattorizza sia l'implementazione che i test 16
  • 17. Test Driven Development (TDD) TDD significa anche 束Test Driven Design損 Permette di definire l'interfaccia degli oggetti prima di buttarsi sull'implementazione Permette di concentrarsi sul comportamento dell'oggetto Permette di rifattorizzare il codice con maggiore confidenza Porta alla realizzazione di architetture con basso accoppiamento 17
  • 18. Test Driven Development (TDD) Con TDD posso anche... Documentare l'utilizzo dei miei componenti attraverso i test Evitare la regressione dei bug Isolare codice legacy Dormire un po' pi湛 tranquillo la sera dopo il rilascio 18
  • 19. Test Driven Development (TDD) TDD non 竪 Unit Testing ...ma sono ottimi amici :) Come testare le interfacce utente? Utilizzando tool ad-hoc Rimuovendo la logica dalle interfacce Come testare liberandosi da risorse esterne? Mock TDD pu嘆 creare dipendenza! :) 19
  • 20. Test Driven Development (TDD) Strumenti: *Unit: JUnit, PyUnit, NUnit, CPPUnit, PHPUnit, ... DBUnit, SQLUnit, PL/SQL Unit, ... EasyMock, Moquer, MockEJB, ... Selenium, HttpUnit, Jmeter, ... Fit, Fitnesse, ... ...forse pure troppi 20
  • 21. Test Driven Development (TDD) DOMANDE? 21
  • 22. Esempi di TDD (Test Driven Development) Roberto Bettazzoni roberto@bettazzoni.it http://creativecommons.org/licenses/by-sa/3.0/ 22
  • 23. Primo Esempio di TDD Prima User Story. Una funzione XML-RPC che, dato il nome di un file presente sul server, ne ritorni il contenuto
  • 24. Primo Esempio di TDD Acceptance test. #!/usr/bin/env python from xmlrpclib import ServerProxy srv = ServerProxy('http://localhost:8000') f = open(__file__, "rt") try: assert srv.load(__file__) == f.read() finally: f.close()
  • 31. test.py import unittest, os from load import * class Test(unittest.TestCase): def test_load_file_not_exists(self): assert load("") == "" try: os.remove("DoNotExist") except OSError: pass assert load("DoNotExist") == "" def test_load_an_existing_file(self): text = "I'm a lumberjack and I'm okay" fname = "TEST.tmp" f = open(fname, "wt") f.write(text) f.close() assert load(fname) == text os.remove(fname) if __name__ == '__main__': unittest.main()
  • 32. load.py def load(name): try: f = open(name, "rt") try: return f.read() finally: f.close() except IOError: return ""
  • 33. test.py import unittest, os, pyprocess, xmlrpclib from load import * def createFile(fname, text): f = open(fname, "wt") f.write(text) f.close() class Test(unittest.TestCase): def test_load_file_not_exists(self): def test_load_an_existing_file(self): ... ... class TestServer(unittest.TestCase): def test(self): proc = pyprocess.PyProcess("load.py") proc.start() createFile("other", "text") try: rpc = xmlrpclib.ServerProxy('http://localhost:8000') assert rpc.load("other") == "text" finally: proc.kill() os.remove("other")
  • 34. load.py import os, SimpleXMLRPCServer def load(name): try: f = open(name, "rt") try: return f.read() finally: f.close() except IOError: return "" if __name__ == '__main__': srv = SimpleXMLRPCServer.SimpleXMLRPCServer(("",8000)) srv.register_function(load) srv.serve_forever()
  • 35. Primo Esempio di TDD Eseguendo il file load.py il test di accettazione gira senza errori. End of Job (?)