tdd reloaded - jugtaa 24 ottobre 2012
DESCRIPTION
Seconda serata di introduzione al Test-Driven Development, tenuta in XPeppers a Trento il 24 Ottobre 2012. Nelle slide c'è anche la descrizione del coding dojo sullo string calculator che abbiamo svolto assieme.TRANSCRIPT
Test-Driven Development
JUG Trentino Alto-AdigeOttobre 2012
Pietro Di [email protected]
twitter: @pierodibellowww.xpeppers.com
Test-Driven Development
JUG Trentino Alto-AdigeOttobre 2012
Pietro Di [email protected]
twitter: @pierodibellowww.xpeppers.com
reloaded
Che cos’è il TDD?
Che cos’è il TDD?
TDD = Test-driven development
Che cos’è il TDD?
TDD = Test-driven development
è una tecnica di sviluppo
Che cos’è il TDD?
TDD = Test-driven development
è una tecnica di sviluppo
inventata da uno sviluppatore
Che cos’è il TDD?
TDD = Test-driven design
è una tecnica di design e di sviluppo
Qual’è l’obbiettivo del TDD?
L’obbiettivo del TDD è scrivere “codice pulito che funziona”
• is out of reach of even the best programmers, some of the time,
• and out of reach of most programmers (like me) most of the time
-- Kent Beck
Clean code that works
Qual’è l’obbiettivo del TDD?
Che cos’è il TDD?
TDD = Test-driven development
guidata dalla scrittura di test automatici unitari
Che cos’è il TDD?
Test automatici e unitari
automatici = le verifiche le fa la macchina al posto
mio
Che cos’è il TDD?
Test automatici e unitari
unitari = non verifico l’intero sistema ma una
singola unità (classe, modulo, funzione)
e allora?
Nel TDD si usano i test automatici per guidare il design e lo sviluppo del codice
Il ritmo del TDD
Il ritmo del TDD
Red — Write a little test that doesn't work, and perhaps doesn't even compile at first.
Il ritmo del TDD
Green — Make the test work quickly, committing whatever sins necessary in the process.
Red — Write a little test that doesn't work, and perhaps doesn't even compile at first.
Il ritmo del TDD
Green — Make the test work quickly, committing whatever sins necessary in the process.
Refactor — Eliminate all of the duplication created in merely getting the test to work.
Red — Write a little test that doesn't work, and perhaps doesn't even compile at first.
Write a test
public class AdderTest { @Test public void testTwoPlusThree() { Adder a = new Adder();
assertEquals(5, a.add(2, 3)); }}
Now it compiles
public class AdderTest { @Test public void testTwoPlusThree() { Adder a = new Adder(); assertEquals(5, a.add(2, 3)); }}
public class Adder { public int add(int a, int b) { return 0; }}
Red bar!
Expected 5, was 0
public class AdderTest { @Test public void testTwoPlusThree() { Adder a = new Adder(); assertEquals(5, a.add(2, 3)); }}
public class Adder { public int add(int a, int b) { return 0; }}
Do the simplest thing
public class AdderTest { @Test public void testTwoPlusThree() { Adder a = new Adder(); assertEquals(5, a.add(2, 3)); }}
public class Adder { public int add(int a, int b) { return 5; }}
Refactor
public class AdderTest { @Test public void testTwoPlusThree() { Adder a = new Adder(); assertEquals(5, a.add(2, 3)); }}
public class Adder { public int add(int a, int b) { return a+b; }}
The procedure
1. Write a test
2. Make it compile
3. Make it pass quickly
4. Refactor to remove duplication
Expected 5, was 0
The procedure
Red
GreenRefactor
Repeat every 2-10 min.
Prima un test che fallisce
Red — Write a little test that doesn't work, and perhaps doesn't even compile at first.
Il codice visto dalla barra rossa
When we write a test, we imagine the perfect interface for our operation. We are telling ourselves a story about how the operation will look from the outside. Our story won't always come true, but it's better to start from the best-possible application program interface (API) and work backward than to make things complicated, ugly, and "realistic" from the get-go.
Kent Beck
Maialino time... :)
Green — Make the test work quickly, committing whatever sins necessary in the process.
Paga per i tuoi debiti...
Refactor — Eliminate all of the duplication created in merely getting the test to work.
Qual’è l’essenza del TDD?
L’essenza del TDD è “sapere sempre quale sarà il prossimo passo”
Qual’è l’essenza del TDD?
L’essenza del TDD è “sapere sempre quale sarà il prossimo passo”
Avere chiara la strada
L’essenza del TDD
Meno stress
L’essenza del TDD
Meno stress
• Progresso misurabile e verificabile
• Copertura di test
• Controllo dello scope
• Riduzione del bug rate
L’essenza del TDD
Progresso misurabile e verificabile
L’essenza del TDD
A piccoli passi
L’essenza del TDD
Copertura di test
L’essenza del TDD
Controllo dello scope funzionale
Uso della TODO list• Utile per gestire la complessità
• elencare i diversi aspetti del problema• NON si elencano i test da implementare
• non è TDD• Riduce lo stress• Bussola per farci capire a che punto siamo
e non ci perdere la strada• Se mi viene in mente qualcosa la scrivo
nella todolist e continuo sulla mia strada senza perdere focus
Quando usare il TDD è difficile?
• Quando si sviluppare codice multithreaded
• Quando si lavora su codice legacy
• Quando si padroneggia poco il linguaggio
di programmazione usato
Cosa non è uno unit-test?
A test is not a unit test if:
• It talks to the database• It communicates across the network• It touches the file system• It can't run at the same time as any of your
other unit tests• You have to do special things to your
environment (such as editing config files) to run it.
Michael Feathers (“A Set of Unit Testing Rules”)
The Three Rules Of TDD
• You are not allowed to write any production code unless it is to make a failing unit test pass.
• You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
• You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
Robert “Uncle Bob” Martin (“The Three Laws of TDD”)
Debugging Sucks
Testing Rocks
• by Roy Osherove
• (http://osherove.com/tdd-kata-1)
String Calculator
Coding Dojo
StringCalculator Kata
• Create a simple String calculator with a method
• int Add(string numbers)
• The method can take zero, one or two numbers, and will return their sum
• for example “” or “1” or “1,2”
• for an empty string it will return 0
Start with the simplest test case of an empty string and move to one and two numbers
StringCalculator Kata
• Remember to solve things as simply as possible so that you force yourself to write tests you did not think about
• Remember to refactor after each passing test
StringCalculator Kata
Allow the Add method to handle an unknown amount of numbers
Allow the Add method to handle new lines between numbers (instead of commas).
• the following input is ok: “1\n2,3” (will equal 6)
• the following input is NOT ok: “1,\n” (not need to prove it - just clarifying)
StringCalculator Kata
Support different delimiters
to change a delimiter, the beginning of the string will contain a separate line that looks like this:
“//[delimiter]\n[numbers…]”
for example “//;\n1;2” should return three where the default delimiter is ‘;’ .
the first line is optional.
all existing scenarios should still be supported
StringCalculator Kata
Calling Add with a negative number will throw an exception “negatives not allowed” - and the negative that was passed.
If there are multiple negatives, show all of them in the exception message
StringCalculator Kata
Numbers bigger than 1000 should be ignored.
So adding 2 + 1001 = 2
StringCalculator Kata
Delimiters can be of any length with the following format:
“//[delimiter]\n”
For example:“//[***]\n1***2***3” returns 6.
StringCalculator Kata
Make sure you can also handle multiple delimiters with length longer than one char
StringCalculator Kata