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