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. Benefits 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 ain’t
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. Benefits of TDD
• Increased confidence 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. Benefits of TDD
• Test act as a "living specification" of expected behaviour
• Smaller production codebases with more simple designs
• Easier detection of flaws 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
that’s overhead.
Rebut - Better than maintaining bug list.
Claim - Effectiveness 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