TDD and the Terminator

TDD and the Terminator

Ac87ebf0cf6b8e9f4e66582ec9845620?s=128

Layla Porter

August 10, 2020
Tweet

Transcript

  1. @LaylaCodesIt

  2. @LaylaCodesIt

  3. @LaylaCodesIt MICROSOFT MVP MK .NET ORGANISER C# LOVER SENIOR DEVELOPER

    EVANGELIST @ LAYLA PORTER
  4. @LaylaCodesIt WHY TDD AND THE TERMINATOR?

  5. @LaylaCodesIt TDD SUCCESSES •Acceptance Criteria •Focus •Interfaces •Asynchronous development •Cleaner

    code •Safe refactoring •Fewer bugs •Increasing returns •Living documentation
  6. @LaylaCodesIt BACK TO THE TERMINATOR

  7. @LaylaCodesIt THE PROCESS

  8. @LaylaCodesIt GATHER THE REQUIREMENTS

  9. @LaylaCodesIt

  10. @LaylaCodesIt Terminator Requirements Scan subjects and determine if they require

    further investigation Investigate subjects of interest and determine if they are the target - TERMINATE!
  11. @LaylaCodesIt Scan subjects and determine if they require further investigation

  12. @LaylaCodesIt START WITH FAILING TESTS

  13. @LaylaCodesIt When you write tests after coding you may be

    writing them to fit your code and not your requirements
  14. @LaylaCodesIt RED/GREEN REFACTOR PATTERN • Write a failing test •

    Write enough code to get the test to pass • Refactor!
  15. @LaylaCodesIt OVER TO CODE

  16. @LaylaCodesIt REFACTOR!

  17. @LaylaCodesIt public bool InvestigateFurther(ISubject subject) { if (subject.SubjectName.ToLower() ==" "woman")

    { return true; } if (subject.SubjectName.ToLower() ==" "girl") { return true; } if (subject.SubjectName.ToLower() ==" "man") { return true; } if (subject.SubjectName.ToLower() ==" "boy") { return true; } return false; }
  18. @LaylaCodesIt public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case

    "woman": case "girl": case "man": case "boy": return true; default: return false; } } public bool InvestigateFurther(ISubject subject) { if (subject.SubjectName.ToLower() ==" "woman") { return true; } if (subject.SubjectName.ToLower() ==" "girl") { return true; } if (subject.SubjectName.ToLower() ==" "man") { return true; } if (subject.SubjectName.ToLower() ==" "boy") { return true; } return false; }
  19. @LaylaCodesIt public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case

    "woman": case "girl": case "man": case "boy": return true; default: return false; } } [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigate Further (string subjectName) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Should().BeTrue(); } [Test] public void TerminatorShould_DetermineNot_ToInvestigateFurther() { var subject = new Subject {SubjectName = "T1000"}; var result = _sut.InvestigateFurther(subject); result.Should().BeFalse(); }
  20. @LaylaCodesIt public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case

    "woman": case "girl": case "man": case "boy": return true; default: return false; } } [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigate Further (string subjectName) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Should().BeTrue(); } [Test] public void TerminatorShould_DetermineNot_ToInvestigateFurther() { var subject = new Subject {SubjectName = "T1000"}; var result = _sut.InvestigateFurther(subject); result.Should().BeFalse(); }
  21. @LaylaCodesIt REQUIREMENT CHANGE!

  22. @LaylaCodesIt

  23. @LaylaCodesIt New Terminator Requirements Protect John and Sarah Connor from

    threats Ability to learn
  24. @LaylaCodesIt public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case

    "woman": case "girl": case "man": case "boy": return true; default: return false; } } [Test] public void TerminatorShould_DetermineNot_ToInvestigateFurther() { var subject = new Subject {SubjectName = "T1000"}; var result = _sut.InvestigateFurther(subject); result.Should().BeFalse(); } TerminatorShould_DetermineNot_ToInvestigateFurther("T1000"): Success
  25. @LaylaCodesIt public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case

    "woman": case "girl": case "man": case "boy": case "T1000": return true; default: return false; } } [Test] public void TerminatorShould_DetermineNot_ToInvestigateFurther() { var subject = new Subject {SubjectName = "T1000"}; var result = _sut.InvestigateFurther(subject); result.Should().BeFalse(); } TerminatorShould_DetermineNot_ToInvestigateFurther("T1000"): Failed: Expected result to be False, but found True
  26. @LaylaCodesIt DESIGNING YOUR APPLICATION TO BE MORE ROBUST

  27. @LaylaCodesIt DESIGN PATTERNS

  28. @LaylaCodesIt DESIGN PATTERNS SOLID PRINCIPLES

  29. @LaylaCodesIt EPENDENCY INVERSION PRINCIPLE S O I D L NTERFACE

    SEGREGATION PRINCIPLE ISKOV SUBSTITUTION PRINCIPLE PEN/CLOSE PRINCIPLE INGLE RESPONSIBILITY PRINCIPLE
  30. @LaylaCodesIt EPENDENCY INVERSION PRINCIPLE S O I D L NTERFACE

    SEGREGATION PRINCIPLE ISKOV SUBSTITUTION PRINCIPLE PEN/CLOSE PRINCIPLE INGLE RESPONSIBILITY PRINCIPLE
  31. @LaylaCodesIt Every class or module in a program should have

    responsibility for just a single piece of that program's functionality. SINGLE RESPONSIBILITY PRINCIPLE
  32. @LaylaCodesIt Software entities (classes, modules, functions, etc.) should be open

    for extension, but closed for modification. OPEN/CLOSE PRINCIPLE
  33. @LaylaCodesIt Objects should be replaceable with instances of their subtypes

    without altering the correctness of that program. LISKOV SUBSTITUTION PRINCIPLE LET'S SEE IT IN ACTION!
  34. @LaylaCodesIt REFACTOR!

  35. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigate Further (string

    subjectName) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Should().BeTrue(); } [Test] public void TerminatorShould_DetermineNot_ToInvestig ateFurther() { var subject = new Subject {SubjectName = "T1000"}; var result = _sut.InvestigateFurther(subject); result.Should().BeFalse(); }
  36. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigate Further (string

    subjectName) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Should().BeTrue(); } [Test] public void TerminatorShould_DetermineNot_ToInvestig ateFurther() { var subject = new Subject {SubjectName = "T1000"}; var result = _sut.InvestigateFurther(subject); result.Should().BeFalse(); } [TestCase("woman", true)] [TestCase("girl", false)] [TestCase("man", false)] [TestCase("boy",true)] [TestCase("T1000",true)] public void TerminatorShould_Determine_ToInvestigate Further (string subjectName, bool outcome) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Equals(outcome); }
  37. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigate Further (string

    subjectName) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Should().BeTrue(); } [Test] public void TerminatorShould_DetermineNot_ToInvestig ateFurther() { var subject = new Subject {SubjectName = "T1000"}; var result = _sut.InvestigateFurther(subject); result.Should().BeFalse(); } [TestCase("woman", true)] [TestCase("girl", false)] [TestCase("man", false)] [TestCase("boy",true)] [TestCase("T1000",true)] public void TerminatorShould_Determine_ToInvestigate Further (string subjectName, bool outcome) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Equals(outcome); }
  38. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigate Further (string

    subjectName) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Should().BeTrue(); } [Test] public void TerminatorShould_DetermineNot_ToInvestig ateFurther() { var subject = new Subject {SubjectName = "T1000"}; var result = _sut.InvestigateFurther(subject); result.Should().BeFalse(); } [TestCase("woman", true)] [TestCase("girl", false)] [TestCase("man", false)] [TestCase("boy",true)] [TestCase("T1000",true)] public void TerminatorShould_Determine_ToInvestigate Further (string subjectName, bool outcome) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Equals(outcome); }
  39. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigate Further (string

    subjectName) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Should().BeTrue(); } [Test] public void TerminatorShould_DetermineNot_ToInvestig ateFurther() { var subject = new Subject {SubjectName = "T1000"}; var result = _sut.InvestigateFurther(subject); result.Should().BeFalse(); } [TestCase("woman", true)] [TestCase("girl", false)] [TestCase("man", false)] [TestCase("boy",true)] [TestCase("T1000",true)] public void TerminatorShould_Determine_ToInvestigate Further (string subjectName, bool outcome) { var subject = new Subject {SubjectName = subject Name}; var result = _sut.InvestigateFurther(subject); result.Equals(outcome); }
  40. @LaylaCodesIt [TestCase("woman", true)] [TestCase("girl", false)] [TestCase("man", false)] [TestCase("boy",true)] [TestCase("T1000",true)] public

    void TerminatorShould_Determine_ToInvestigateFurther(string subjectName, bool outcome) { var subject = new Subject {SubjectName = subjectName}; var result = _sut.InvestigateFurther(subject); result.Equals(outcome); } TerminatorShould_Determine_ToInvestigateFurther (5 tests) Success TerminatorShould_Determine_ToInvestigateFurther("T1000",True) Success TerminatorShould_Determine_ToInvestigateFurther("man",False) Success TerminatorShould_Determine_ToInvestigateFurther("girl",False) Success TerminatorShould_Determine_ToInvestigateFurther("boy",True) Success TerminatorShould_Determine_ToInvestigateFurther("woman",True) Success
  41. @LaylaCodesIt public interface ISubject { string SubjectName { get; set;

    } } public class Subject : ISubject { public string SubjectName { get; set; } } public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case "woman": case "girl": case "man": case "boy": case "T1000": return true; default: return false; } }
  42. @LaylaCodesIt public interface ISubject { string SubjectName { get; set;

    } } public class Subject : ISubject { public string SubjectName { get; set; } } public interface ISubjectRule { bool IsMatch(Subject subject); bool OfInterest(); } public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case "woman": case "girl": case "man": case "boy": case "T1000": return true; default: return false; } }
  43. @LaylaCodesIt public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case

    "woman": case "girl": case "man": case "boy": case "T1000": return true; default: return false; } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } }
  44. @LaylaCodesIt public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case

    "woman": case "girl": case "man": case "boy": case "T1000": return true; default: return false; } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } }
  45. @LaylaCodesIt public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case

    "woman": case "girl": case "man": case "boy": case "T1000": return true; default: return false; } } public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule> _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } }
  46. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  47. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  48. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  49. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  50. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  51. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  52. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  53. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  54. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  55. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  56. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule rule = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(rule); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class IsWomanRule : ISubjectRule { public bool OfInterest() { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public class IsDogRule : ISubjectRule { public bool OfInterest() { return false; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("dog"); } }
  57. @LaylaCodesIt If you need to make a private method public

    in order to test it, then it's time to refactor
  58. @LaylaCodesIt public bool MethodOne() { throw new NotImplementedException(); } CODE

    SMELL!! public bool MethodTwo() { throw new NotImplementedException(); }
  59. @LaylaCodesIt ISP splits interfaces that are very large into smaller

    and more specific ones so that implementations will only have to know about the methods that are of interest to them INTERFACE SEGREGATION PRINCIPLE
  60. @LaylaCodesIt public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule());

    _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { var isMatch =_subjectRules.FirstOrDefault(r =>$ r.IsMatch(subject)); return Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } TerminatorShould_Determine_ToInvestigateFurther (5 tests) Success TerminatorShould_Determine_ToInvestigateFurther("dog",False) Success TerminatorShould_Determine_ToInvestigateFurther("woman",True) Success
  61. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch = Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule> _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch = Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } }
  62. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); _subjectRules.Add(new IsBoyRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch = Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule> _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch = Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } }
  63. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); _subjectRules.Add(new IsBoyRule()); _subjectRules.Add(new IsManRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch = Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule> _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch = Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } }
  64. @LaylaCodesIt public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule>

    _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); _subjectRules.Add(new IsBoyRule()); _subjectRules.Add(new IsManRule()); _subjectRules.Add(new IsT1000Rule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch = Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } } public class SubjectAnalyser : ISubjectAnalyser { private readonly List<ISubjectRule> _subjectRules; public SubjectAnalyser() { _subjectRules = new List<ISubjectRule>(); _subjectRules.Add(new IsWomanRule()); _subjectRules.Add(new IsDogRule()); } public bool InvestigateFurther(Subject subject) { ISubjectRule isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch = Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } }
  65. @LaylaCodesIt WITH GOOD PRACTICES, CODE MANAGEMENT BECOMES INFINITELY EASIER

  66. @LaylaCodesIt TDD FAILURES •Underestimating the learning curve •Confusing TDD with

    unit testing •Thinking TDD is enough testing •Not starting with failing tests •Not refactoring enough •Not actually doing TDD!
  67. @LaylaCodesIt IMPLEMENTATION WITHIN YOUR ORGANIZATION •Can be controversial and is

    a significant culture change •Initial drop in productivity can be disconcerting •Productivity will go up and reworks reduced •Increased understanding of requirements and their acceptance criteria
  68. @LaylaCodesIt IF YOU TAKE ONE THING AWAY FROM THIS TALK...

  69. @LaylaCodesIt [Test] public void TerminatorShould_Determine_ToInvestigateFurther (ISubject subject) { var subject

    = new Subject{SubjectName = "woman"}; var result = _sut.InfestigateFurther(subject); result.Should().BeTrue(); }
  70. @LaylaCodesIt [Test] public void TerminatorShould_Determine_ToInvestigateFurther (ISubject subject) { var subject

    = new Subject{SubjectName = "woman"}; var result = _sut.InfestigateFurther(subject); result.Should().BeTrue(); } public bool _sut.InvestigateFurther(ISubject subject) { return true; }
  71. @LaylaCodesIt [Test] public void TerminatorShould_Determine_ToInvestigateFurther (ISubject subject) { var subject

    = new Subject{SubjectName = "woman"}; var result = _sut.InfestigateFurther(subject); result.Should().BeTrue(); } public bool _sut.InvestigateFurther(ISubject subject) { return true; } Write the least amount of code to get your test to pass. Return true!
  72. @LaylaCodesIt Twitter: @LaylaCodesIt GitHub: Layla-P Email: lporter@twilio.com Repo: http://bit.ly/tdd-terminator Deck:

    http://bit.ly/tdd-deck Twitch: twitch.tv/LaylaCodesIt Yaks: https://bit.ly/shaving-a-yak