Introduzione al TDD

Andrea Francia
Andrea FranciaFull Stack Something at 7Pixel S.r.l.
Introduzione al
Test Driven Development
Andrea Francia
http://www.andreafrancia.it
Contents
Concepts
Definition
Example1: Parser
Example2: Text To Speech
Concepts
Test First
Automate tests
What is a Automated
Test?
Automated Test Lifecycle
Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
Automated Test Lifecycle
Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
Automated Test Lifecycle
SUT: System Under Test
Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
Automated Test Lifecycle
SUT: System Under Test
Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
Automated Test Lifecycle
SUT: System Under Test
Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
Example of a Manual Test:
nextLine()
public static void main(String[] args) {
String text = "first linensecond line";
Scanner scanner = new Scanner(text);
System.out.println(scanner.nextLine()); // prints
"first line"
System.out.println(scanner.nextLine()); // prints
"second line”
}
Code:
assertEquals(expected, actual);
PASS FAIL
expected == actual
yes no
Using JUnit
@Test public void howNextLineWorks() throws IOException {
String text = "first linensecond line";
Scanner scanner = new Scanner(text);
assertEquals(”first line", scanner.nextLine());
assertEquals(”second line", scanner.nextLine());
}
Code:
Output:
What is Test Driven
Development?
What is TDD?
Test-driven development (TDD) is a software
development process that relies on the repetition of a
very short development cycle:
Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
Tim Ottinger:http://agileinaflash.blogspot.com/2009/02/red-green-refactor.html
RED
first the developer writes a failing automated test case
that defines a desired new behaviour (of the software),
GREEN
then produces code to pass that test …
Refactor
and finally refactors the new code to acceptable standards.
Introduzione al TDD
Example:
Writing “df” Parser
The df output
[andreafrancia@deneb Dropbox]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/disk0s2 243862672 135971832 107634840 56% /
/dev/disk0s1 243862672 135971832 107634840 56% /tmp
/dev/disk1s2 243862672 135971832 107634840 56% /opt
devfs 109 109 0 100% /dev
Mount Points
The problem
List all mount points
The Problem
Write a method that extract the list of the mount points
from the output of df.
First of all decompose
the problem!
Decomposition
Parse the output of “df” process …
When there are no mounted volumes
When there is only one volume mounted
When there are many volumes
When the a volume contains whitespaces
First Cycle
Parse the output of “df” process
When there are no volumes
When there is only one volume
When there are many volumes
When the a volume contains whitespaces
@Test
public void whenNoVolumes() {
String input = "Filesystem 1024-blocks Used Available Capacity
Mounted on”;
List<String> result = parseDfOutput(input);
assertEquals(emptyList(), result);
}
Introduzione al TDD
@Test
public void whenNoVolumes() {
String input = "Filesystem 1024-blocks Used Available Capacity
Mounted on”;
List<String> result = parseDfOutput(input);
assertEquals(emptyList(), result);
}
private List<String> parseDfOutput(String string) {
return null;
}
@Test
public void whenNoVolumes() {
String input = "Filesystem 1024-blocks Used Available Capacity
Mounted on”;
List<String> result = parseDfOutput(input);
assertEquals(emptyList(), result);
}
private List<String> parseDfOutput(String string) {
return emptyList();
}
No need for refactoring
Second Cycle
Parse the output of “df” process
When there are no volumes
When there is only one volume
When there are many volumes
When the a volume contains whitespaces
@Test public void whenOneVolume() {
List<String> result = parseDfOutput(""
+ "Filesystem 1024-blocks Used Available Capacity Mounted
onn"
+ "/dev/disk0s2 243862672 135479924 108126748 56% /");
assertEquals(asList("/"), result);
}
private List<String> parseDfOutput(String string) {
return emptyList();
}
private List<String> parseDfOutput(String string) {
List<String> result = new ArrayList<String>();
return result;
}
private List<String> parseDfOutput(String input) {
List<String> result = new ArrayList<String>();
Scanner scanner = new Scanner(input);
scanner.nextLine(); // skip header
if(scanner.hasNextLine()) {
String line = scanner.nextLine();
Scanner scanner1 = new Scanner(line);
scanner1.next(); // skip Filesystem
scanner1.next(); // skip 1024-blocks
scanner1.next(); // skip Used
scanner1.next(); // skip Available
scanner1.next(); // skip Capacity
String mountPoint = scanner1.next();
result.add(mountPoint);
}
return result;
}
private List<String> parseDfOutput(String input) {
List<String> result = new ArrayList<String>();
Scanner lines = new Scanner(input);
lines.nextLine(); // skip header
if(lines.hasNextLine()) {
String line = lines.nextLine();
Scanner values = new Scanner(line);
values.next(); // skip Filesystem
values.next(); // skip 1024-blocks
values.next(); // skip Used
values.next(); // skip Available
values.next(); // skip Capacity
String mountPoint = values.next();
result.add(mountPoint);
}
return result;
}
private List<String> parseDfOutput(String input) {
List<String> result = new ArrayList<String>();
Scanner lines = new Scanner(input);
lines.nextLine(); // skip header
if(lines.hasNextLine()) {
result.add(parseMountPoint(lines.nextLine()));
}
return result;
}
private String parseMountPoint(String line) {
Scanner values = new Scanner(line);
values.next(); // skip Filesystem
values.next(); // skip 1024-blocks
values.next(); // skip Used
values.next(); // skip Available
values.next(); // skip Capacity
String mountPoint = values.next();
return mountPoint;
}
Third Cycle
Parse the output of “df” process
When there are no volumes
When there is only one volume
When there are many volumes
When the a volume contains whitespaces
@Test public void whenMultipleVolume() {
List<String> result = parseDfOutput(""
+ "Filesystem 1024-blocks Used Available Capacity Mounted
onn"
+ "/dev/disk0s2 243862672 135479924 108126748 56% /n"
+ "/dev/disk0s2 243862672 135479924 108126748 56%
/media/diskn"
+ "/dev/disk0s2 243862672 135479924 108126748 56%
/tmpn");
assertEquals(asList("/", "/media/disk", "/tmp"), result);
}
@Test public void whenMultipleVolume() {
List<String> result = parseDfOutput(""
+ "Filesystem 1024-blocks Used Available Capacity Mounted
onn"
+ "/dev/disk0s2 243862672 135479924 108126748 56% /n"
+ "/dev/disk0s2 243862672 135479924 108126748 56%
/media/diskn"
+ "/dev/disk0s2 243862672 135479924 108126748 56%
/tmpn");
assertEquals(asList("/", "/media/disk", "/tmp"), result);
}
private List<String> parseDfOutput(String input) {
List<String> result = new ArrayList<String>();
Scanner lines = new Scanner(input);
lines.nextLine(); // skip header
if(lines.hasNextLine()) {
String line = lines.nextLine();
String mountPoint = parseMountPoint(line);
result.add(mountPoint);
}
return result;
}
private List<String> parseDfOutput(String input) {
List<String> result = new ArrayList<String>();
Scanner lines = new Scanner(input);
lines.nextLine(); // skip header
while(lines.hasNextLine()) {
String line = lines.nextLine();
String mountPoint = parseMountPoint(line);
result.add(mountPoint);
}
return result;
}
TDD Rules
TDD Rules
Test First
Test for All Features
Remove all duplication
(always)
Some hints
Keep tests running and passing
Keeps test small
Don’t mix phases (Red, Green,
Refactor)
Don’t mix unit tests with integration
tests
Test only one feature per test
Examples from my last
work
Regole applicate
Ogni feature deve essere sviluppata secondo il
TDD
Partire dai test di accettazione
Ritardare le decisioni di design all’ultimo
momento responsabile
Applicare un principio di design solo dopo aver
avuto la prova che sia utile in quel specifico caso
Prima feature: produrre
testo pronunciabile
Test di accettazione
public class HoroscopeTest {
@Test public void
userListenOroscope() {
Horoscope horoscope = new Horoscope();
horoscope.saveDivination("22-GIU-10", "Ariete",
"Sarai molto fortunato.");
String result =
horoscope.GET("/horoscope/ariete.txt");
assertEquals("22 giugno 2010: Ariete, Sarai
molto fortunato.”, result);
}
No test  No code
Quando scrivo il codice di produzione scrivo il
minimo necessario a far passare il test
Se il minimo non mi convince (è troppo stupido),
vuol dire che manca una specifica funzionale 
cioè manca un test.
Prima di scrivere una qualsiasi riga di codice in
più aggiungo un test che la richieda.
@Test public void
shouldStoreDivinationsForMultipleSigns() {
Horoscope horoscope = new Horoscope();
horoscope.saveDivination("22-GIU-10", "Ariete",
"for ariete");
horoscope.saveDivination("22-GIU-10", "Toro",
"for toro");
assertEquals("22 giugno 2010: Ariete, for ariete",
horoscope.GET("/horoscope/ariete.txt"));
assertEquals("22 giugno 2010: Toro, for toro",
horoscope.GET("/horoscope/toro.txt"));
}
Cerco di non anticipare il
design
Prima di affrontare lo sviluppo faccio una veloce sessione
di design
Non implemento nessuna decisione fino a che non si
rende necessaria
E.g. anche servirà un DAO per adesso salvo tutto in RAM
Seconda Feature:
oroscopo ascoltabile
@Test public void howToCreateMp3() {
Horoscope horoscope = new Horoscope(
aFakeSyntetizerWhichReturns(
aMp3Stream()));
horoscope.saveDivination("22-GIU-10", "Ariete",
"divination");
assertThat(horoscope.GET(
"/horoscope/ariete.mp3").asByteArray(),
is(equalTo(aMp3Stream())));
}
Resource
Ora il GET restituisce una Resource
 public Resource GET(String path) {...}
Il client decide quale rappresentazione usare:
horoscope.GET("/horoscope/ariete/divination.txt").asString());
horoscope.GET("/horoscope/ariete/divination.mp3").asByteArray();
Terza feature: la
persistenza
Stato delle cose
Al momento tutto viene persistito in memoria (in una
HashMap)
Non esiste ancora un oggetto DAO, tutto viene fatto
dall’unica class Horoscope
Estrazione del comportamento
public class MemoryDivinationRepo {
Divination lastDivinationForSign(String sign);
void saveDivinationFromPronounce(String sign,
String pronounce);
};
public interface Divination {
String asText();
byte[] asMp3();
};
Estrazione dell’interfaccia
public class MemoryDivinationRepo
implements DivinationRepo {...}
public interface DivinationRepo {
Divination lastDivinationForSign(String sign);
void saveDivinationFromPronounce(String sign,
String pronounce);
};
Caratterizzazione del
comportamento
L’interfaccia è una minima parte del contratto, la parte
più importante è il comportamento che l’oggetto
dovrebbe avere.
Il comportamento lo estraggo con dei test di
caratterizzazione
Caratterizzazione di
MemoryDivinationRepo
public class MemoryDivinationRepoTest {
@Test public void
shouldStoreDivinationPronounceForASign() {...}
@Test public void
shouldReplyWithAPronouncedMp3() {...}
@Test public void
shouldStoreDivinationPronounceForMultipleSigns()
{...}
@Test public void
shouldOverrideDivinationPronounce() {...}
}
Thanks
Andrea Francia
www.andreafrancia.it
blog.andreafrancia.it
andrea@andreafrancia.it
Extra slides
Example of an Automated Test
@Test public void shouldParsePath() {
String content =
"[Trash Info]n"
+ "Path=/home/andrea/foo.txtn"
+ "DeletionDate=2010-08-23T12:59:14n";
String path = Parser.parsePath(content);
assertEquals("/home/andrea/foo.txt”,
path);
}
Testing Frameworks
http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks
•PHPUnit
•SimpleTest
•Google C++ Testing Framework
•CppUnitLite
•CppUnit
•JUnit
•TestNG
•PyUnit
•Nose
1 of 65

Recommended

Google C++ Testing Framework in Visual Studio 2008 by
Google C++ Testing Framework in Visual Studio 2008Google C++ Testing Framework in Visual Studio 2008
Google C++ Testing Framework in Visual Studio 2008Andrea Francia
4.8K views22 slides
An introduction to Google test framework by
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test frameworkAbner Chih Yi Huang
9.2K views40 slides
C++ Unit Test with Google Testing Framework by
C++ Unit Test with Google Testing FrameworkC++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkHumberto Marchezi
7.4K views52 slides
20111018 boost and gtest by
20111018 boost and gtest20111018 boost and gtest
20111018 boost and gtestWill Shen
1.5K views28 slides
Test Driven Development With Python by
Test Driven Development With PythonTest Driven Development With Python
Test Driven Development With PythonSiddhi
18.9K views42 slides
GMock framework by
GMock frameworkGMock framework
GMock frameworkcorehard_by
5.3K views34 slides

More Related Content

What's hot

15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp) by
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)Danny Preussler
1.8K views23 slides
Automated testing in Python and beyond by
Automated testing in Python and beyondAutomated testing in Python and beyond
Automated testing in Python and beyonddn
1.7K views20 slides
Golang dot-testing-lite by
Golang dot-testing-liteGolang dot-testing-lite
Golang dot-testing-liteRichárd Kovács
52 views24 slides
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how by
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski
1.2K views40 slides
Modern Python Testing by
Modern Python TestingModern Python Testing
Modern Python TestingAlexander Loechel
2.4K views36 slides
Python unittest by
Python unittestPython unittest
Python unittestFelipe Ruhland
486 views31 slides

What's hot(19)

15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp) by Danny Preussler
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
Danny Preussler1.8K views
Automated testing in Python and beyond by dn
Automated testing in Python and beyondAutomated testing in Python and beyond
Automated testing in Python and beyond
dn 1.7K views
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how by Tomasz Polanski
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski1.2K views
Python-nose: A unittest-based testing framework for Python that makes writing... by Timo Stollenwerk
Python-nose: A unittest-based testing framework for Python that makes writing...Python-nose: A unittest-based testing framework for Python that makes writing...
Python-nose: A unittest-based testing framework for Python that makes writing...
Timo Stollenwerk5.7K views
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system by Tarin Gamberini
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
Tarin Gamberini2.1K views
Advanced junit and mockito by Mathieu Carbou
Advanced junit and mockitoAdvanced junit and mockito
Advanced junit and mockito
Mathieu Carbou4.9K views
unittest in 5 minutes by Ray Toal
unittest in 5 minutesunittest in 5 minutes
unittest in 5 minutes
Ray Toal1.8K views
Javaone2008 Bof 5101 Groovytesting by Andres Almiray
Javaone2008 Bof 5101 GroovytestingJavaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 Groovytesting
Andres Almiray960 views
Unit Testing Presentation by nicobn
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
nicobn629 views
Google mock for dummies by Harry Potter
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
Harry Potter1.9K views
Python Unit Test by David Xie
Python Unit TestPython Unit Test
Python Unit Test
David Xie1.5K views
Python Testing Fundamentals by cbcunc
Python Testing FundamentalsPython Testing Fundamentals
Python Testing Fundamentals
cbcunc4K views

Viewers also liked

Tutti i miei sbagli (Errori di un wannabe Open Source Developer) by
Tutti i miei sbagli (Errori di un wannabe Open Source Developer)Tutti i miei sbagli (Errori di un wannabe Open Source Developer)
Tutti i miei sbagli (Errori di un wannabe Open Source Developer)Andrea Francia
5.2K views148 slides
Piccolo coding dojo (milano xpug 2013-04-11) by
Piccolo coding dojo (milano xpug 2013-04-11)Piccolo coding dojo (milano xpug 2013-04-11)
Piccolo coding dojo (milano xpug 2013-04-11)Andrea Francia
1.2K views36 slides
Subversion @ JUG Milano 11 dic 2009 by
Subversion @ JUG Milano 11 dic 2009Subversion @ JUG Milano 11 dic 2009
Subversion @ JUG Milano 11 dic 2009Andrea Francia
1.3K views25 slides
Tutti i miei sbagli, versione 7 Marzo 2012 al XPUG mi by
Tutti i miei sbagli, versione 7 Marzo 2012 al XPUG miTutti i miei sbagli, versione 7 Marzo 2012 al XPUG mi
Tutti i miei sbagli, versione 7 Marzo 2012 al XPUG miAndrea Francia
1.4K views50 slides
Working Effectively with Legacy Code (draft) by
Working Effectively with Legacy Code (draft)Working Effectively with Legacy Code (draft)
Working Effectively with Legacy Code (draft)Andrea Francia
1.6K views16 slides
Le 12 pratiche by
Le 12 praticheLe 12 pratiche
Le 12 praticheAndrea Francia
431 views31 slides

Viewers also liked(12)

Tutti i miei sbagli (Errori di un wannabe Open Source Developer) by Andrea Francia
Tutti i miei sbagli (Errori di un wannabe Open Source Developer)Tutti i miei sbagli (Errori di un wannabe Open Source Developer)
Tutti i miei sbagli (Errori di un wannabe Open Source Developer)
Andrea Francia5.2K views
Piccolo coding dojo (milano xpug 2013-04-11) by Andrea Francia
Piccolo coding dojo (milano xpug 2013-04-11)Piccolo coding dojo (milano xpug 2013-04-11)
Piccolo coding dojo (milano xpug 2013-04-11)
Andrea Francia1.2K views
Subversion @ JUG Milano 11 dic 2009 by Andrea Francia
Subversion @ JUG Milano 11 dic 2009Subversion @ JUG Milano 11 dic 2009
Subversion @ JUG Milano 11 dic 2009
Andrea Francia1.3K views
Tutti i miei sbagli, versione 7 Marzo 2012 al XPUG mi by Andrea Francia
Tutti i miei sbagli, versione 7 Marzo 2012 al XPUG miTutti i miei sbagli, versione 7 Marzo 2012 al XPUG mi
Tutti i miei sbagli, versione 7 Marzo 2012 al XPUG mi
Andrea Francia1.4K views
Working Effectively with Legacy Code (draft) by Andrea Francia
Working Effectively with Legacy Code (draft)Working Effectively with Legacy Code (draft)
Working Effectively with Legacy Code (draft)
Andrea Francia1.6K views
Writing a Crawler with Python and TDD by Andrea Francia
Writing a Crawler with Python and TDDWriting a Crawler with Python and TDD
Writing a Crawler with Python and TDD
Andrea Francia1.9K views
20070514 introduction to test ng and its application for test driven gui deve... by Will Shen
20070514 introduction to test ng and its application for test driven gui deve...20070514 introduction to test ng and its application for test driven gui deve...
20070514 introduction to test ng and its application for test driven gui deve...
Will Shen867 views
Bade Smells in Code by Will Shen
Bade Smells in CodeBade Smells in Code
Bade Smells in Code
Will Shen3K views
Monogdb in general by Ido Kanner
Monogdb in generalMonogdb in general
Monogdb in general
Ido Kanner680 views

Similar to Introduzione al TDD

Appium TestNG Framework and Multi-Device Automation Execution by
Appium TestNG Framework and Multi-Device Automation ExecutionAppium TestNG Framework and Multi-Device Automation Execution
Appium TestNG Framework and Multi-Device Automation ExecutionpCloudy
201 views10 slides
3 j unit by
3 j unit3 j unit
3 j unitkishoregali
1.8K views73 slides
33rd Degree 2013, Bad Tests, Good Tests by
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
1K views79 slides
Java practical by
Java practicalJava practical
Java practicalwilliam otto
341 views16 slides
2012 JDays Bad Tests Good Tests by
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good TestsTomek Kaczanowski
802 views74 slides
16. Java stacks and queues by
16. Java stacks and queues16. Java stacks and queues
16. Java stacks and queuesIntro C# Book
4.8K views46 slides

Similar to Introduzione al TDD(20)

Appium TestNG Framework and Multi-Device Automation Execution by pCloudy
Appium TestNG Framework and Multi-Device Automation ExecutionAppium TestNG Framework and Multi-Device Automation Execution
Appium TestNG Framework and Multi-Device Automation Execution
pCloudy201 views
16. Java stacks and queues by Intro C# Book
16. Java stacks and queues16. Java stacks and queues
16. Java stacks and queues
Intro C# Book4.8K views
Learning Java 1 – Introduction by caswenson
Learning Java 1 – IntroductionLearning Java 1 – Introduction
Learning Java 1 – Introduction
caswenson1.6K views
Lambda Chops - Recipes for Simpler, More Expressive Code by Ian Robertson
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
Ian Robertson602 views
Some testing - Everything you should know about testing to go with @pedro_g_s... by Sergio Arroyo
Some testing - Everything you should know about testing to go with @pedro_g_s...Some testing - Everything you should know about testing to go with @pedro_g_s...
Some testing - Everything you should know about testing to go with @pedro_g_s...
Sergio Arroyo1.4K views
Grails unit testing by pleeps
Grails unit testingGrails unit testing
Grails unit testing
pleeps4.1K views

More from Andrea Francia

Baby Steps TripServiceKata by
Baby Steps TripServiceKataBaby Steps TripServiceKata
Baby Steps TripServiceKataAndrea Francia
389 views39 slides
TDD on Legacy Code - Voxxed Days Milano 2019 by
TDD on Legacy Code - Voxxed Days Milano 2019TDD on Legacy Code - Voxxed Days Milano 2019
TDD on Legacy Code - Voxxed Days Milano 2019Andrea Francia
291 views18 slides
Lavorare con codice legacy “non testabile” - Incontro DevOps - 8 marzo 2019 -... by
Lavorare con codice legacy “non testabile” - Incontro DevOps - 8 marzo 2019 -...Lavorare con codice legacy “non testabile” - Incontro DevOps - 8 marzo 2019 -...
Lavorare con codice legacy “non testabile” - Incontro DevOps - 8 marzo 2019 -...Andrea Francia
506 views24 slides
Kata in Bash a DevOpsHeroes 2018 a Parma by
Kata in Bash a DevOpsHeroes 2018 a ParmaKata in Bash a DevOpsHeroes 2018 a Parma
Kata in Bash a DevOpsHeroes 2018 a ParmaAndrea Francia
150 views6 slides
User Stories - Andrea Francia @ WeDev 7 novembre 2018 by
User Stories - Andrea Francia @ WeDev 7 novembre 2018User Stories - Andrea Francia @ WeDev 7 novembre 2018
User Stories - Andrea Francia @ WeDev 7 novembre 2018Andrea Francia
459 views94 slides
Le pratiche ingegneristiche di eXtreme Programming by
Le pratiche ingegneristiche di eXtreme ProgrammingLe pratiche ingegneristiche di eXtreme Programming
Le pratiche ingegneristiche di eXtreme ProgrammingAndrea Francia
467 views135 slides

More from Andrea Francia(12)

TDD on Legacy Code - Voxxed Days Milano 2019 by Andrea Francia
TDD on Legacy Code - Voxxed Days Milano 2019TDD on Legacy Code - Voxxed Days Milano 2019
TDD on Legacy Code - Voxxed Days Milano 2019
Andrea Francia291 views
Lavorare con codice legacy “non testabile” - Incontro DevOps - 8 marzo 2019 -... by Andrea Francia
Lavorare con codice legacy “non testabile” - Incontro DevOps - 8 marzo 2019 -...Lavorare con codice legacy “non testabile” - Incontro DevOps - 8 marzo 2019 -...
Lavorare con codice legacy “non testabile” - Incontro DevOps - 8 marzo 2019 -...
Andrea Francia506 views
Kata in Bash a DevOpsHeroes 2018 a Parma by Andrea Francia
Kata in Bash a DevOpsHeroes 2018 a ParmaKata in Bash a DevOpsHeroes 2018 a Parma
Kata in Bash a DevOpsHeroes 2018 a Parma
Andrea Francia150 views
User Stories - Andrea Francia @ WeDev 7 novembre 2018 by Andrea Francia
User Stories - Andrea Francia @ WeDev 7 novembre 2018User Stories - Andrea Francia @ WeDev 7 novembre 2018
User Stories - Andrea Francia @ WeDev 7 novembre 2018
Andrea Francia459 views
Le pratiche ingegneristiche di eXtreme Programming by Andrea Francia
Le pratiche ingegneristiche di eXtreme ProgrammingLe pratiche ingegneristiche di eXtreme Programming
Le pratiche ingegneristiche di eXtreme Programming
Andrea Francia467 views
Test-Driven Development su Codice Esistente by Andrea Francia
Test-Driven Development su Codice EsistenteTest-Driven Development su Codice Esistente
Test-Driven Development su Codice Esistente
Andrea Francia107 views
Le 12 pratiche - Un introduzione a XP (Mini Italian Agile Day) by Andrea Francia
Le 12 pratiche - Un introduzione a XP (Mini Italian Agile Day)Le 12 pratiche - Un introduzione a XP (Mini Italian Agile Day)
Le 12 pratiche - Un introduzione a XP (Mini Italian Agile Day)
Andrea Francia799 views
Introduzione a eXtreme Programming by Andrea Francia
Introduzione a eXtreme ProgrammingIntroduzione a eXtreme Programming
Introduzione a eXtreme Programming
Andrea Francia279 views
Test-Driven Development e Sviluppo Incrementale (TDD-Milano 2017-01-10) by Andrea Francia
Test-Driven Development e Sviluppo Incrementale (TDD-Milano 2017-01-10)Test-Driven Development e Sviluppo Incrementale (TDD-Milano 2017-01-10)
Test-Driven Development e Sviluppo Incrementale (TDD-Milano 2017-01-10)
Andrea Francia271 views

Recently uploaded

217 Drive - All on upper.pptx by
217 Drive - All on upper.pptx217 Drive - All on upper.pptx
217 Drive - All on upper.pptxvidstor282
16 views7 slides
IEC 600068-2-39 ENVIROMENT TESTING COMBINED TEMPERATURE LOW HUMIDTY.pdf by
IEC 600068-2-39 ENVIROMENT TESTING COMBINED TEMPERATURE LOW HUMIDTY.pdfIEC 600068-2-39 ENVIROMENT TESTING COMBINED TEMPERATURE LOW HUMIDTY.pdf
IEC 600068-2-39 ENVIROMENT TESTING COMBINED TEMPERATURE LOW HUMIDTY.pdfNirmalanGanapathy1
11 views36 slides
Anti-Cancer Drugs-Medicinal Chemistry by
Anti-Cancer Drugs-Medicinal ChemistryAnti-Cancer Drugs-Medicinal Chemistry
Anti-Cancer Drugs-Medicinal ChemistryNarminHamaaminHussen
9 views41 slides
JAWARK Inside Company Profile 2024 by
JAWARK Inside Company Profile 2024JAWARK Inside Company Profile 2024
JAWARK Inside Company Profile 2024mostafareda1994
7 views45 slides
Sudden Deafness Design Document by
Sudden Deafness Design DocumentSudden Deafness Design Document
Sudden Deafness Design Documentwyfangherman
50 views19 slides
The Report is Dead, Long Live the Report ! Communicating Usability Research F... by
The Report is Dead, Long Live the Report ! Communicating Usability Research F...The Report is Dead, Long Live the Report ! Communicating Usability Research F...
The Report is Dead, Long Live the Report ! Communicating Usability Research F...Centralis
5 views72 slides

Recently uploaded(20)

217 Drive - All on upper.pptx by vidstor282
217 Drive - All on upper.pptx217 Drive - All on upper.pptx
217 Drive - All on upper.pptx
vidstor28216 views
IEC 600068-2-39 ENVIROMENT TESTING COMBINED TEMPERATURE LOW HUMIDTY.pdf by NirmalanGanapathy1
IEC 600068-2-39 ENVIROMENT TESTING COMBINED TEMPERATURE LOW HUMIDTY.pdfIEC 600068-2-39 ENVIROMENT TESTING COMBINED TEMPERATURE LOW HUMIDTY.pdf
IEC 600068-2-39 ENVIROMENT TESTING COMBINED TEMPERATURE LOW HUMIDTY.pdf
Sudden Deafness Design Document by wyfangherman
Sudden Deafness Design DocumentSudden Deafness Design Document
Sudden Deafness Design Document
wyfangherman50 views
The Report is Dead, Long Live the Report ! Communicating Usability Research F... by Centralis
The Report is Dead, Long Live the Report ! Communicating Usability Research F...The Report is Dead, Long Live the Report ! Communicating Usability Research F...
The Report is Dead, Long Live the Report ! Communicating Usability Research F...
Centralis5 views
Using Experiential Design to Understand the Future of AI & Immersive Storytel... by Kent Bye
Using Experiential Design to Understand the Future of AI & Immersive Storytel...Using Experiential Design to Understand the Future of AI & Immersive Storytel...
Using Experiential Design to Understand the Future of AI & Immersive Storytel...
Kent Bye10 views
Free World aids day Template from Best presentation design agency by slideceotemplates
Free World aids day Template from Best presentation design agencyFree World aids day Template from Best presentation design agency
Free World aids day Template from Best presentation design agency
Oregon Ducks 4 Spencer Webb Hoodie by brandshop1
Oregon Ducks 4 Spencer Webb HoodieOregon Ducks 4 Spencer Webb Hoodie
Oregon Ducks 4 Spencer Webb Hoodie
brandshop113 views

Introduzione al TDD

  • 1. Introduzione al Test Driven Development Andrea Francia http://www.andreafrancia.it
  • 4. What is a Automated Test?
  • 5. Automated Test Lifecycle Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
  • 6. Automated Test Lifecycle Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
  • 7. Automated Test Lifecycle SUT: System Under Test Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
  • 8. Automated Test Lifecycle SUT: System Under Test Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
  • 9. Automated Test Lifecycle SUT: System Under Test Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies
  • 10. Example of a Manual Test: nextLine() public static void main(String[] args) { String text = "first linensecond line"; Scanner scanner = new Scanner(text); System.out.println(scanner.nextLine()); // prints "first line" System.out.println(scanner.nextLine()); // prints "second line” } Code:
  • 12. Using JUnit @Test public void howNextLineWorks() throws IOException { String text = "first linensecond line"; Scanner scanner = new Scanner(text); assertEquals(”first line", scanner.nextLine()); assertEquals(”second line", scanner.nextLine()); } Code: Output:
  • 13. What is Test Driven Development?
  • 14. What is TDD? Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: Giordano Scalzo: http://www.slideshare.net/giordano/tdd-iphonefordummies Tim Ottinger:http://agileinaflash.blogspot.com/2009/02/red-green-refactor.html
  • 15. RED first the developer writes a failing automated test case that defines a desired new behaviour (of the software),
  • 16. GREEN then produces code to pass that test …
  • 17. Refactor and finally refactors the new code to acceptable standards.
  • 20. The df output [andreafrancia@deneb Dropbox]$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/disk0s2 243862672 135971832 107634840 56% / /dev/disk0s1 243862672 135971832 107634840 56% /tmp /dev/disk1s2 243862672 135971832 107634840 56% /opt devfs 109 109 0 100% /dev Mount Points
  • 21. The problem List all mount points
  • 22. The Problem Write a method that extract the list of the mount points from the output of df.
  • 23. First of all decompose the problem!
  • 24. Decomposition Parse the output of “df” process … When there are no mounted volumes When there is only one volume mounted When there are many volumes When the a volume contains whitespaces
  • 25. First Cycle Parse the output of “df” process When there are no volumes When there is only one volume When there are many volumes When the a volume contains whitespaces
  • 26. @Test public void whenNoVolumes() { String input = "Filesystem 1024-blocks Used Available Capacity Mounted on”; List<String> result = parseDfOutput(input); assertEquals(emptyList(), result); }
  • 28. @Test public void whenNoVolumes() { String input = "Filesystem 1024-blocks Used Available Capacity Mounted on”; List<String> result = parseDfOutput(input); assertEquals(emptyList(), result); } private List<String> parseDfOutput(String string) { return null; }
  • 29. @Test public void whenNoVolumes() { String input = "Filesystem 1024-blocks Used Available Capacity Mounted on”; List<String> result = parseDfOutput(input); assertEquals(emptyList(), result); } private List<String> parseDfOutput(String string) { return emptyList(); }
  • 30. No need for refactoring
  • 31. Second Cycle Parse the output of “df” process When there are no volumes When there is only one volume When there are many volumes When the a volume contains whitespaces
  • 32. @Test public void whenOneVolume() { List<String> result = parseDfOutput("" + "Filesystem 1024-blocks Used Available Capacity Mounted onn" + "/dev/disk0s2 243862672 135479924 108126748 56% /"); assertEquals(asList("/"), result); }
  • 33. private List<String> parseDfOutput(String string) { return emptyList(); }
  • 34. private List<String> parseDfOutput(String string) { List<String> result = new ArrayList<String>(); return result; }
  • 35. private List<String> parseDfOutput(String input) { List<String> result = new ArrayList<String>(); Scanner scanner = new Scanner(input); scanner.nextLine(); // skip header if(scanner.hasNextLine()) { String line = scanner.nextLine(); Scanner scanner1 = new Scanner(line); scanner1.next(); // skip Filesystem scanner1.next(); // skip 1024-blocks scanner1.next(); // skip Used scanner1.next(); // skip Available scanner1.next(); // skip Capacity String mountPoint = scanner1.next(); result.add(mountPoint); } return result; }
  • 36. private List<String> parseDfOutput(String input) { List<String> result = new ArrayList<String>(); Scanner lines = new Scanner(input); lines.nextLine(); // skip header if(lines.hasNextLine()) { String line = lines.nextLine(); Scanner values = new Scanner(line); values.next(); // skip Filesystem values.next(); // skip 1024-blocks values.next(); // skip Used values.next(); // skip Available values.next(); // skip Capacity String mountPoint = values.next(); result.add(mountPoint); } return result; }
  • 37. private List<String> parseDfOutput(String input) { List<String> result = new ArrayList<String>(); Scanner lines = new Scanner(input); lines.nextLine(); // skip header if(lines.hasNextLine()) { result.add(parseMountPoint(lines.nextLine())); } return result; } private String parseMountPoint(String line) { Scanner values = new Scanner(line); values.next(); // skip Filesystem values.next(); // skip 1024-blocks values.next(); // skip Used values.next(); // skip Available values.next(); // skip Capacity String mountPoint = values.next(); return mountPoint; }
  • 38. Third Cycle Parse the output of “df” process When there are no volumes When there is only one volume When there are many volumes When the a volume contains whitespaces
  • 39. @Test public void whenMultipleVolume() { List<String> result = parseDfOutput("" + "Filesystem 1024-blocks Used Available Capacity Mounted onn" + "/dev/disk0s2 243862672 135479924 108126748 56% /n" + "/dev/disk0s2 243862672 135479924 108126748 56% /media/diskn" + "/dev/disk0s2 243862672 135479924 108126748 56% /tmpn"); assertEquals(asList("/", "/media/disk", "/tmp"), result); }
  • 40. @Test public void whenMultipleVolume() { List<String> result = parseDfOutput("" + "Filesystem 1024-blocks Used Available Capacity Mounted onn" + "/dev/disk0s2 243862672 135479924 108126748 56% /n" + "/dev/disk0s2 243862672 135479924 108126748 56% /media/diskn" + "/dev/disk0s2 243862672 135479924 108126748 56% /tmpn"); assertEquals(asList("/", "/media/disk", "/tmp"), result); }
  • 41. private List<String> parseDfOutput(String input) { List<String> result = new ArrayList<String>(); Scanner lines = new Scanner(input); lines.nextLine(); // skip header if(lines.hasNextLine()) { String line = lines.nextLine(); String mountPoint = parseMountPoint(line); result.add(mountPoint); } return result; }
  • 42. private List<String> parseDfOutput(String input) { List<String> result = new ArrayList<String>(); Scanner lines = new Scanner(input); lines.nextLine(); // skip header while(lines.hasNextLine()) { String line = lines.nextLine(); String mountPoint = parseMountPoint(line); result.add(mountPoint); } return result; }
  • 44. TDD Rules Test First Test for All Features Remove all duplication (always)
  • 45. Some hints Keep tests running and passing Keeps test small Don’t mix phases (Red, Green, Refactor) Don’t mix unit tests with integration tests Test only one feature per test
  • 46. Examples from my last work
  • 47. Regole applicate Ogni feature deve essere sviluppata secondo il TDD Partire dai test di accettazione Ritardare le decisioni di design all’ultimo momento responsabile Applicare un principio di design solo dopo aver avuto la prova che sia utile in quel specifico caso
  • 49. Test di accettazione public class HoroscopeTest { @Test public void userListenOroscope() { Horoscope horoscope = new Horoscope(); horoscope.saveDivination("22-GIU-10", "Ariete", "Sarai molto fortunato."); String result = horoscope.GET("/horoscope/ariete.txt"); assertEquals("22 giugno 2010: Ariete, Sarai molto fortunato.”, result); }
  • 50. No test  No code Quando scrivo il codice di produzione scrivo il minimo necessario a far passare il test Se il minimo non mi convince (è troppo stupido), vuol dire che manca una specifica funzionale  cioè manca un test. Prima di scrivere una qualsiasi riga di codice in più aggiungo un test che la richieda.
  • 51. @Test public void shouldStoreDivinationsForMultipleSigns() { Horoscope horoscope = new Horoscope(); horoscope.saveDivination("22-GIU-10", "Ariete", "for ariete"); horoscope.saveDivination("22-GIU-10", "Toro", "for toro"); assertEquals("22 giugno 2010: Ariete, for ariete", horoscope.GET("/horoscope/ariete.txt")); assertEquals("22 giugno 2010: Toro, for toro", horoscope.GET("/horoscope/toro.txt")); }
  • 52. Cerco di non anticipare il design Prima di affrontare lo sviluppo faccio una veloce sessione di design Non implemento nessuna decisione fino a che non si rende necessaria E.g. anche servirà un DAO per adesso salvo tutto in RAM
  • 54. @Test public void howToCreateMp3() { Horoscope horoscope = new Horoscope( aFakeSyntetizerWhichReturns( aMp3Stream())); horoscope.saveDivination("22-GIU-10", "Ariete", "divination"); assertThat(horoscope.GET( "/horoscope/ariete.mp3").asByteArray(), is(equalTo(aMp3Stream()))); }
  • 55. Resource Ora il GET restituisce una Resource  public Resource GET(String path) {...} Il client decide quale rappresentazione usare: horoscope.GET("/horoscope/ariete/divination.txt").asString()); horoscope.GET("/horoscope/ariete/divination.mp3").asByteArray();
  • 57. Stato delle cose Al momento tutto viene persistito in memoria (in una HashMap) Non esiste ancora un oggetto DAO, tutto viene fatto dall’unica class Horoscope
  • 58. Estrazione del comportamento public class MemoryDivinationRepo { Divination lastDivinationForSign(String sign); void saveDivinationFromPronounce(String sign, String pronounce); }; public interface Divination { String asText(); byte[] asMp3(); };
  • 59. Estrazione dell’interfaccia public class MemoryDivinationRepo implements DivinationRepo {...} public interface DivinationRepo { Divination lastDivinationForSign(String sign); void saveDivinationFromPronounce(String sign, String pronounce); };
  • 60. Caratterizzazione del comportamento L’interfaccia è una minima parte del contratto, la parte più importante è il comportamento che l’oggetto dovrebbe avere. Il comportamento lo estraggo con dei test di caratterizzazione
  • 61. Caratterizzazione di MemoryDivinationRepo public class MemoryDivinationRepoTest { @Test public void shouldStoreDivinationPronounceForASign() {...} @Test public void shouldReplyWithAPronouncedMp3() {...} @Test public void shouldStoreDivinationPronounceForMultipleSigns() {...} @Test public void shouldOverrideDivinationPronounce() {...} }
  • 64. Example of an Automated Test @Test public void shouldParsePath() { String content = "[Trash Info]n" + "Path=/home/andrea/foo.txtn" + "DeletionDate=2010-08-23T12:59:14n"; String path = Parser.parsePath(content); assertEquals("/home/andrea/foo.txt”, path); }
  • 65. Testing Frameworks http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks •PHPUnit •SimpleTest •Google C++ Testing Framework •CppUnitLite •CppUnit •JUnit •TestNG •PyUnit •Nose

Editor's Notes

  1. Questa presentazione è una breve introduzione al Test Driven Development. Questa è una presentazione rivolta a chi: - ha sentito parlare della tecnica - che non l’ha ancora provata o ha appena iniziato - e che vorrebbe saperne qualcosa di più. Non c’è nessun argomento avanzato, solo un assaggio. Gli obiettivi della presentazione sono: spiegare di cosa si tratta fornirvi un idea di quello che permette di fare spiegare i vantaggi dell’approcio Non è una trattazione completa dell’argomento. Per riuscire ad usarla con profitto sarebbe necessario almeno leggere alcuni libri che eventualmente dopo indicherò oppure meglio ancora lavorare con qualcuno bravo che la usa.
  2. Questi sono I contenuti della presenazione. Partiremo dallo spiegare brevemente i concetti che sono dietro alla tecnica. Esporremo la meccanica alla base della del processo. Infine vedremo due esemp. Un esempio sullo sviluppo in TDD di un parser. Un esempio tratto dal un mio recente lavoro.
  3. Io ho individuato due concetti alla base del TDD. Test First Il primo è scrivere il test prima. Cioe’ scriverlo prima che il codice di produzione sia creato. Questo perche’ l’altra strategia, il test after, non funziona. O almeno funziona male. I problemi con il test after sono che: - alla fine il test non viene scritto - testare del codice che non e’ pensato per essere testato puo’ essere veramente molto difficile Invece con il test first si riesce a definire a priori sia l’interfaccia del codice da sviluppare sia il comportamento che il codice deve avere. Automate your tests L’altro aspetto fondamentale è che tutti i test vengono automatizzati. Il motivo è semplice testare a mano è noioso. Ricompilare, avviare il programma, inserire gli input necessari per attivare quel particolare pezzo di codice che stiamo scrivendo è lungo e tedioso. Scrivere test automatici richiede un certo tempo, ma dopo aver fatto un po’ di pratica con gli strumenti il tempo è di meno di quello necessario per scrivere il test automatico.
  4. L’interfaccia si evolve  La GET() non era adatta per gestire sia testo che gli mp3 Nasce il concetto di Resource L’interfaccia si evolve per supportare le nuove funzionalità senza rovinare il design
  5. Nota: refactoring anche dei test scritti precedentemente che saranno adattati alla nuova API.
  6. Nella slide è riportato un esempio di test. Questo esempio di test riguarda lo sviluppo di un applicazione che gestisce il cestino di Linux. Quando in buttiamo un file nel cestino il sistema si deve ricordare alcuni metadati come il path da cui il file e’ stato “rimosso” e la data in cui questa cosa e’ successa. In Linux queste informazioni sono memorizzate in un file di testo che ha una sintassi simile alla stringa content che vedete nelle slide. Questo è un test per il metodo parse() della classe TrashInfo e verifica che sia in grado di leggere il contenuto del file passato in input. La caratteristica importante di questi test è che il controllo dell’esito è automatico, in altre parole che non é necessaria l’ispezione o il controllo da parte dello sviluppatore. L’altro aspetto importante é l’esecuzione é molto veloce perché non ci sono operazioni di I/O. Questo tipo di test è chiamato test di unità.