Upload
sameer-soni
View
188
Download
1
Embed Size (px)
Citation preview
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.
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); } } }
Write enough to compile
public class LifeRules { public static CellState GetNewState(CellState cellState, int neighbourCount) { throw new System.NotImplementedException(); } }
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; } }
General Test Structure
Minimum Setup for Test (Given)
Invoke the event (When)
Verify assertions (Then)
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); }
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; } }
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); }
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; } }
Refactored Codepublic class LifeRules { public static CellState GetNewState(CellState currentState, int neighbourCount) { switch (currentState) { case CellState.ALIVE: if (neighbourCount < 2 || neighbourCount > 3) return CellState.DEAD; break; case CellState.DEAD: if (neighbourCount == 3) return CellState.ALIVE; break; } return currentState; } }
Crux of TDD
• Analysing the minimalistic need of story and implementing it in the cleanest way possible
• Design the code unit by unit
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
TDD results in decoupled design
• Favours composition over inheritance.
• Small loosely coupled classes.
• Promotes coding to supertypes.
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
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
Removes Code Smells• Duplicate Code
• Long methods
• Classes with too much code
• Lot of unused code
• Too many private methods
• Excessive Overloading
Costs of TDDClaim - Slower per-feature development work because tests take a lot of time to writeRebut - 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.
Good Test are
• Small
• Expressive
• Maintainable
• Should execute fast
• talk Domain language
• must be thorough
• automated
• repeatable
Unit testing frameworks
• JUnit/TestNG for Java
• NUnit/MsTest for C#
• Minitest/TestUnit for Ruby
• pyUnit/unittest for Python