2. What TDD is not
is not about Testing
is not Test Last
3. What TDD is
is about
evolving the design of the system through Tests.
4. Game Of Life - Stories
1. Any live cell with fewer than two live neighbours dies, as if caused by
under-population.
2. Any live cell with two or three live neighbours lives on to the next
generation.
3. Any live cell with more than three live neighbours dies, as if by
overcrowding.
4. Any dead cell with exactly three live neighbours becomes a live cell, as
if by reproduction.
5. Specify what test should do
[TestClass]
public
class
GameOfLifeTest
{
[TestMethod]
public
void
LiveCell_WithLessThanTwoNeighbour_Dies()
{
//Given
CellState
cellState
=
CellState.ALIVE;
int
neighbourCount
=
1;
//When
CellState
result
=
LifeRules.GetNewState(cellState,
neighbourCount);
//Then
Assert.AreEqual(CellState.DEAD,
result);
}
}
}
6. Write enough to compile
public
class
LifeRules
{
public
static
CellState
GetNewState(CellState
cellState,
int
neighbourCount)
{
throw
new
System.NotImplementedException();
}
}
8. Write enough to pass your
test
public
class
LifeRules
{
public
static
CellState
GetNewState(CellState
currentState,
int
neighbourCount)
{
if
(currentState
==
CellState.ALIVE
&&
neighbourCount
<
2)
{
return
CellState.DEAD;
}
return
currentState;
}
}
11. Add Test for next story
[TestMethod]
public
void
LiveCell_WithTwoOrThreeNeighbour_Survives()
{
//Given
CellState
cellState
=
CellState.ALIVE;
int
neighbourCount
=
3;
//When
CellState
result
=
LifeRules.GetNewState(cellState,
neighbourCount);
//Then
Assert.AreEqual(CellState.ALIVE,
result);
}
12. Add Implementation
public
class
LifeRules
{
public
static
CellState
GetNewState(CellState
currentState,
int
neighbourCount)
{
if
(currentState
==
CellState.ALIVE
&&
neighbourCount
<
2)
{
return
CellState.DEAD;
}
if
(currentState
==
CellState.ALIVE
&&
neighbourCount
>
3)
{
return
CellState.DEAD;
}
return
currentState;
}
}
13. Add Test for two more stories
[TestMethod]
public
void
LiveCell_WithMoreThanThreeNeighbour_Dies()
{
//Given
CellState
cellState
=
CellState.ALIVE;
int
neighbourCount
=
4;
//When
CellState
result
=
LifeRules.GetNewState(cellState,
neighbourCount);
//Then
Assert.AreEqual(CellState.DEAD,
result);
}
[TestMethod]
public
void
DeadCell_WithThreeNeighbour_Lives()
{
//Given
CellState
cellState
=
CellState.DEAD;
int
neighbourCount
=
3;
//When
CellState
result
=
LifeRules.GetNewState(cellState,
neighbourCount);
//Then
Assert.AreEqual(CellState.ALIVE,
result);
}
14. Add remaining implementations
public
class
LifeRules
{
public
static
CellState
GetNewState(CellState
currentState,
int
neighbourCount)
{
if
(currentState
==
CellState.ALIVE
&&
neighbourCount
<
2)
{
return
CellState.DEAD;
}
if
(currentState
==
CellState.ALIVE
&&
neighbourCount
>
3)
{
return
CellState.DEAD;
}
if
(currentState
==
CellState.DEAD
&&
neighbourCount
==
3)
{
return
CellState.ALIVE;
}
return
currentState;
}
}
18. Crux of TDD
Analysing the minimalistic need of story and
implementing it in the cleanest way possible
Design the code unit by unit
19. Bene鍖ts of TDD
Deliver what is necessary.
Helps take baby steps.
System so developed does just what is required, no
more, no less.
No future stories development (YAGNI - You aint
gonna need it).
Better Code Coverage
20. TDD results in decoupled design
Favours composition over inheritance.
Small loosely coupled classes.
Promotes coding to supertypes.
21. Bene鍖ts of TDD
Increased con鍖dence in developers working on test-
driven codebases
Better code quality (in particular, less coupling and
higher cohesion)
Improved maintainability and changeability of
codebases
Ability to refactor without fear of breaking things
22. Bene鍖ts of TDD
Test act as a "living speci鍖cation" of expected behaviour
Smaller production codebases with more simple designs
Easier detection of 鍖aws in the interactions between
objects
Reduced need for manual testing
Faster feedback loop for discovering whether an
implementation is correct
23. Removes Code Smells
Duplicate Code
Long methods
Classes with too much code
Lot of unused code
Too many private methods
Excessive Overloading
24. Costs of TDD
Claim - Slower per-feature development work because tests take
a lot of time to write
Rebut - Prevents speculative design and living with debugger.
Claim - Tests are code in themselves, require maintenance and
thats overhead.
Rebut - Better than maintaining bug list.
Claim - E鍖ectiveness is highly dependent on experience/
discipline of dev team.
Rebut - TDD is not a silver bullet. Just like with any skill, one
needs time to hone their skills.
25. Good Test are
Small
Expressive
Maintainable
Should execute fast
talk Domain language
must be thorough
automated
repeatable