Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TDD and the Terminator

Layla Porter
September 05, 2019

TDD and the Terminator

Getting started with Test Driven Development (TDD) can be very challenging. It requires a different mindset and approach to writing and developing code. However, once in that mindset, it is very difficult not to write tests first.

But why bother writing tests first?

In this session, we will go through the reasons for writing tests before coding, look at architecture and design principles, such as SOLID and see how it all comes together to create a more testable and maintainable application.

I will show you how to get started writing tests first with practical examples on how to reprogram a T800 series Terminator so you can start using TDD in your own applications (or killer robots from the future).

Hasta La Vista badly-written code!

Layla Porter

September 05, 2019
Tweet

More Decks by Layla Porter

Other Decks in Programming

Transcript

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

    code •Safe refactoring •Fewer bugs •Increasing returns •Living documentation
  2. @LaylaCodesIt Terminator Requirements Scan subjects and determine if they require

    further investigation Investigate subjects of interest and determine if they are the target - TERMINATE!
  3. @LaylaCodesIt When you write tests after coding you may be

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

    Write enough code to get the test to pass • Refactor!
  5. @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; }
  6. @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; }
  7. @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_ToInvestigateFurther (string subjectName) { var subject = new Subject {SubjectName = subjectName}; 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(); }
  8. @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_ToInvestigateFurther (string subjectName) { var subject = new Subject {SubjectName = subjectName}; 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(); }
  9. @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
  10. @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
  11. @LaylaCodesIt EPENDENCY INVERSION PRINCIPLE S O I D L NTERFACE

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

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

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

    for extension, but closed for modification. OPEN/CLOSE PRINCIPLE
  15. @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!
  16. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigateFurther (string subjectName)

    { var subject = new Subject {SubjectName = subjectName}; 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(); }
  17. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigateFurther (string subjectName)

    { var subject = new Subject {SubjectName = subjectName}; 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(); } [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); }
  18. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigateFurther (string subjectName)

    { var subject = new Subject {SubjectName = subjectName}; 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(); } [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); }
  19. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigateFurther (string subjectName)

    { var subject = new Subject {SubjectName = subjectName}; 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(); } [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); }
  20. @LaylaCodesIt [TestCase("woman")] [TestCase("girl")] [TestCase("man")] [TestCase("boy")] public void TerminatorShould_Determine_ToInvestigateFurther (string subjectName)

    { var subject = new Subject {SubjectName = subjectName}; 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(); } [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); }
  21. @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
  22. @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 interface ISubject { string SubjectName { get; set; } } public class Subject : ISubject { public string SubjectName { get; set; } }
  23. @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; } }
  24. @LaylaCodesIt public class IsWomanRule : ISubjectRule { public bool OfInterest()

    { return true; } public bool IsMatch(Subject subject) { return subject.SubjectName.ToLower().Contains("woman"); } } public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case "woman": case "girl": case "man": case "boy": case "T1000": return true; default: return false; } }
  25. @LaylaCodesIt 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"); } } public bool InvestigateFurther(ISubject subject) { switch (subject.SubjectName.ToLower()) { case "woman": case "girl": case "man": case "boy": case "T1000": return true; default: return false; } }
  26. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.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; } }
  27. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  28. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  29. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  30. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  31. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  32. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  33. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  34. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  35. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  36. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  37. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } 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"); } }
  38. @LaylaCodesIt If you need to make a private method public

    in order to test it, then it's time to refactor
  39. @LaylaCodesIt public SubjectAnalysisService() { _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 isMatch ==" null || 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
  40. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || 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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } }
  41. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || 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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } }
  42. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || 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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } }
  43. @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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || 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) { var isMatch = _subjectRules .FirstOrDefault(r =>$ r.IsMatch(subject)); return isMatch ==" null || Investigate(isMatch); } private bool Investigate(ISubjectRule rule) { return rule.OfInterest(); } }
  44. @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!
  45. @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
  46. @LaylaCodesIt [Test] public void TerminatorShould_Determine_ToInvestigateFurther (ISubject subject) { var subject

    = new Subject{SubjectName = "woman"}; var result = _sut.InfestigateFurther(subject); result.Should().BeTrue(); }
  47. @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; }
  48. @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!