How to Tame TDD

How to Tame TDD

TDD is one of the most controversial subjects in the software industry. Its promises are many: a codebase that continuously checks itself, reduces maintainability costs, simplifies introduction of changes, and allows faster work cycles. Unfortunately, high expectations lead to high disappointments. Many good teams have found themselves enchained in webs of mock objects that not only hindered every promise made by TDD originally, but were more costly to maintain than the codebase itself! No wonder why TDD has been declared as waste by many respected professionals. Heck, I was hit by TDD's dark side myself... but found a way to slay the complexity dragon. In this session I'm going to share what I've learned the hard way: how to make peace with mock objects, how to avoid accidental complexities, and ultimately, how to make TDD work for you.

B90ab53ba7cf16ed1a4bb679cc6751d7?s=128

Vladik Khononov

November 17, 2017
Tweet

Transcript

  1. 16 – 17 November, Sofia ISTACON.ORG How to Tame TDD

    By Vladik Khononov
  2. 16 – 17 November, Sofia ISTACON.ORG My twitter is I

    blog Chief Architect My email is vladik
 @ vladikk @ vladikk.com @ Naxex @ khononov.com

  3. 16 – 17 November, Sofia ISTACON.ORG

  4. 16 – 17 November, Sofia ISTACON.ORG Agenda TDD Journey Fix

    #1: Scoping Unit Tests Fix #2: Testing Strategies Common misconceptions Fix #3: TDD & Design TDD Revisited Cyclomatic Complexity Business Logic Modeling Patterns
  5. 16 – 17 November, Sofia ISTACON.ORG

  6. 16 – 17 November, Sofia ISTACON.ORG

  7. 16 – 17 November, Sofia ISTACON.ORG • TDD?

  8. 16 – 17 November, Sofia ISTACON.ORG • TDD? • Done

    TDD?
  9. 16 – 17 November, Sofia ISTACON.ORG • TDD? • Done

    TDD? • Still doing TDD?
  10. 16 – 17 November, Sofia ISTACON.ORG Our TDD Journey

  11. 16 – 17 November, Sofia ISTACON.ORG TDD

  12. 16 – 17 November, Sofia ISTACON.ORG

  13. 16 – 17 November, Sofia ISTACON.ORG v1

  14. 16 – 17 November, Sofia ISTACON.ORG v1

  15. 16 – 17 November, Sofia ISTACON.ORG v1

  16. 16 – 17 November, Sofia ISTACON.ORG v1 v2 UNIT
 TESTS

  17. 16 – 17 November, Sofia ISTACON.ORG

  18. 16 – 17 November, Sofia ISTACON.ORG

  19. 16 – 17 November, Sofia ISTACON.ORG

  20. 16 – 17 November, Sofia ISTACON.ORG v1 v2 UNIT
 TESTS

  21. 16 – 17 November, Sofia ISTACON.ORG v1 v2 UNIT
 TESTS

  22. 16 – 17 November, Sofia ISTACON.ORG v1 v2 v5 OH

    SHIT!
  23. 16 – 17 November, Sofia ISTACON.ORG v1 v2 v5 OH

    SHIT!
  24. 16 – 17 November, Sofia ISTACON.ORG v1 v2 v5 OH

    SHIT!
  25. 16 – 17 November, Sofia ISTACON.ORG Test Code

  26. 16 – 17 November, Sofia ISTACON.ORG Fixing failed tests Test

    Code
  27. 16 – 17 November, Sofia ISTACON.ORG v1 v2 v5 OH

    SHIT!
  28. 16 – 17 November, Sofia ISTACON.ORG v5 v1 v2 OH

    SHIT!
  29. 16 – 17 November, Sofia ISTACON.ORG v5 v1 v2

  30. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test
  31. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test
  32. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test Fakes Mocks Stubs
  33. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test • Refactor Fakes Mocks Stubs
  34. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test • Refactor Fakes Mocks Stubs
  35. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test • Refactor • Repeat • 100% unit test coverage • Maintainable and extendable code • FAST!!! Fakes Mocks Stubs
  36. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test • Refactor • Repeat • 100% unit test coverage • Maintainable and extendable code • FAST!!! Fakes Mocks Stubs
  37. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test • Refactor • Repeat • 100% unit test coverage • Maintainable and extendable code • FAST!!! Fakes Mocks Stubs
  38. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test • Refactor • Repeat • 100% unit test coverage • Maintainable and extendable code • FAST!!! Fakes Mocks Stubs TEST-DRIVEN DESIGN
  39. 16 – 17 November, Sofia ISTACON.ORG Fakes Mocks Stubs •

    Write a failing Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test • Refactor • Repeat • 100% unit test coverage • Maintainable and extendable code • FAST!!! TEST-DRIVEN DESIGN
  40. 16 – 17 November, Sofia ISTACON.ORG Fakes Mocks Stubs •

    Write a failing Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test • Refactor • Repeat • 100% unit test coverage • Maintainable and extendable code • FAST!!! TEST-DRIVEN DESIGN
  41. 16 – 17 November, Sofia ISTACON.ORG Fakes Mocks Stubs •

    Write a failing Unit Test • Write code to a make it pass • Proper design • Isolate the Class under test • Refactor • Repeat • 100% unit test coverage • Maintainable and extendable code • FAST!!! TEST-DRIVEN DESIGN
  42. 16 – 17 November, Sofia ISTACON.ORG What is a Unit?

  43. 16 – 17 November, Sofia ISTACON.ORG CLASS?

  44. 16 – 17 November, Sofia ISTACON.ORG

  45. 16 – 17 November, Sofia ISTACON.ORG •OOP Only CLASS?

  46. 16 – 17 November, Sofia ISTACON.ORG •OOP Only •Fragile CLASS?

  47. 16 – 17 November, Sofia ISTACON.ORG Unit

  48. 16 – 17 November, Sofia ISTACON.ORG Mock Stub Mock Stub

    Stub Stub Unit
  49. 16 – 17 November, Sofia ISTACON.ORG

  50. 16 – 17 November, Sofia ISTACON.ORG

  51. 16 – 17 November, Sofia ISTACON.ORG

  52. 16 – 17 November, Sofia ISTACON.ORG •OOP Only •Fragile •No!

    CLASS?
  53. 16 – 17 November, Sofia ISTACON.ORG ” “ A unit

    is a single logical functional use case in the system that can be invoked by some
 public interface… A unit can span a single method, a whole class or multiple classes working together to achieve one single logical purpose Roy Osherove The Art of Unit Testing
  54. 16 – 17 November, Sofia ISTACON.ORG

  55. 16 – 17 November, Sofia ISTACON.ORG List Task Status *

    1
  56. 16 – 17 November, Sofia ISTACON.ORG Task List Status Units

  57. 16 – 17 November, Sofia ISTACON.ORG Task List Status Units

  58. 16 – 17 November, Sofia ISTACON.ORG Create a new list

    Create a new task Mark as completed Update list name Units
  59. 16 – 17 November, Sofia ISTACON.ORG Unit Test: Create a

    new task List Task Status
  60. 16 – 17 November, Sofia ISTACON.ORG Unit Test: Create a

    new task List Task Status Database Online Calendar Isolate External systems
  61. 16 – 17 November, Sofia ISTACON.ORG • Align Units with

    the system’s use cases • Do not isolate implementation details • Isolate external systems and services Adjustment #1
  62. 16 – 17 November, Sofia ISTACON.ORG Why Unit Tests?

  63. 16 – 17 November, Sofia ISTACON.ORG Unit Tests Integration Tests

    End to End Tests
  64. 16 – 17 November, Sofia ISTACON.ORG Number of tests *

    Execution time = Feedback time
  65. 16 – 17 November, Sofia ISTACON.ORG

  66. 16 – 17 November, Sofia ISTACON.ORG

  67. 16 – 17 November, Sofia ISTACON.ORG * Execution time =

    Feedback time Number of tests
  68. 16 – 17 November, Sofia ISTACON.ORG * Execution time =

    Feedback time Number of tests
  69. 16 – 17 November, Sofia ISTACON.ORG public User(long id, Agency

    agency, User createdBy, DateTime createdOn) : base(createdBy, createdOn) { this.Id = id; this.agency = agency; this.AutoLeadAssignmentPausedUntil = DateTime.UtcNow; } public User(Agency agency, User createdBy, DateTime createdOn) : base(createdBy, createdOn) { this.agency = agency; this.AutoLeadAssignmentPausedUntil = DateTime.UtcNow; } public virtual void AddGroup(Group group) { RemoveGroupsWithOtherDesks(group.Desk); groups.AddIfNotExists(group); if (!group.Users.Contains(this)) group.AddUser(this, false); } public virtual void SetActive(bool value) { if (value && !this.Active) this.StatisticsShouldBeRecalculated = true; this.Active = value; } private void RemoveGroupsWithOtherDesks(Desk newDesk) { if (newDesk == Desk) return; foreach (var g in groups) g.RemoveUser(this); groups.Clear(); } public virtual void AddOrganizationUnit(OrganizationUnitUserAssociation ouUserAssociation) { if (organizationUnitsAssociations.All(x => x.Unit.Id != ouUserAssociation.Unit.Id)) organizationUnitsAssociations.Add(ouUserAssociation); } public virtual Desk[] GetManagedDesks(Advertiser advertiser) { return this.CanAccessAllDesks ? advertiser.Desks.ToArray() : this.ManagesDesks.ToArray(); } public virtual Group[] GetManagedGroups(Advertiser advertiser) { return this.CanAccessAllDesks ? advertiser.Desks.SelectMany(x => x.Groups).Distinct().ToArray() : GetManagedDesks(advertiser) .SelectMany(x => x.Groups) .Concat(this.Groups.Where(x => x.IsManagedBy(this))) .Distinct() .ToArray(); } public virtual Advertiser[] GetAllowedAdvertisers()
  70. 16 – 17 November, Sofia ISTACON.ORG Number of independent execution

    paths within a section of code Cyclomatic Complexity
  71. 16 – 17 November, Sofia ISTACON.ORG DoSomething DoSomethingElse ExecuteSomething ExecuteSomethingElse

    Low C. Complexity
  72. 16 – 17 November, Sofia ISTACON.ORG if(SomeCondition()) DoSomething(); else DoSomethingElse();

    if(AnotherCondition()) ExecuteSomething(); else ExecuteSomethingElse(); High C. Complexity
  73. 16 – 17 November, Sofia ISTACON.ORG Cyclomatic
 Complexity Amount
 of

    Tests
  74. 16 – 17 November, Sofia ISTACON.ORG M = E −

    N + 2P M = E − N + 2 M = π − s + 2
  75. 16 – 17 November, Sofia ISTACON.ORG

  76. 16 – 17 November, Sofia ISTACON.ORG Cyclomatic
 Complexity Amount
 of

    Tests
  77. 16 – 17 November, Sofia ISTACON.ORG Business Logic Modeling Patterns

  78. 16 – 17 November, Sofia ISTACON.ORG Transaction Script Active Record

    Domain Model Business Logic Modeling Patterns
  79. 16 – 17 November, Sofia ISTACON.ORG Simple logic Extract, Transform

    and Load Procedural code Transaction Script
  80. 16 – 17 November, Sofia ISTACON.ORG JSON XML JSON2XML

  81. 16 – 17 November, Sofia ISTACON.ORG Source Database IMPORT

  82. 16 – 17 November, Sofia ISTACON.ORG DB.StartTransaction(); var job =

    DB.LoadNextJob();
 var json = LoadFile(source); var xml = ConvertJsonToXml(json); WriteFile(destionation, xml.ToString(); DB.MarkJobAsCompleted(job); DB.Commit()
  83. 16 – 17 November, Sofia ISTACON.ORG Simple logic ETL-Like processes

    Procedural code Transaction Script
  84. 16 – 17 November, Sofia ISTACON.ORG Unit INTEGRATION END2END

  85. 16 – 17 November, Sofia ISTACON.ORG Complex data structures Simple

    logic CRUD Active Record
  86. 16 – 17 November, Sofia ISTACON.ORG Advertiser Ad Campaign Placement

    * 1 * Location Website Creatives *
  87. 16 – 17 November, Sofia ISTACON.ORG Complex data structures Simple

    logic CRUD Active Record
  88. 16 – 17 November, Sofia ISTACON.ORG

  89. 16 – 17 November, Sofia ISTACON.ORG Active Record Presentation Layer

    Active Records Service / Application Layer Data Structures Business Logic
  90. 16 – 17 November, Sofia ISTACON.ORG public class User {

    public Guid Id { get; set; }
 public string Name { get; set; }
 public List<Interest> Interests { get; set; }
 public Address Address { get; set; } public void Save() { … }
 public void Delete() { … }
 public static User Get(Guid id) { … }
 public static List<User> GetAll() { … } }
  91. 16 – 17 November, Sofia ISTACON.ORG Active Record Presentation Layer

    Service / Application Layer Active Records Data Structures Business Logic
  92. 16 – 17 November, Sofia ISTACON.ORG public class CreateUser {

    public void Execute(userDetails) { try { DB.StartTransaction();
 var user = new User();
 user.Name = userDetails.Name;
 user.Email = userDetails.Email;
 user.Save();
 DB.Commit(); } catch { DB.Rollback();
 throw; } } }
  93. 16 – 17 November, Sofia ISTACON.ORG public class User {

    public Guid Id { get; set; }
 public string Name { get; set; }
 public List<Interest> Interests { get; set; }
 public Address Address { get; set; } public void Save() { … }
 public void Delete() { … }
 public static User Get(Guid id) { … }
 public static List<User> GetAll() { … } }
  94. 16 – 17 November, Sofia ISTACON.ORG public class CreateUser {

    public void Execute(userDetails) { try { DB.StartTransaction();
 var user = new User();
 user.Name = userDetails.Name;
 user.Email = userDetails.Email;
 user.Save();
 DB.Commit(); } catch { DB.Rollback();
 throw; } } }
  95. 16 – 17 November, Sofia ISTACON.ORG INTEGRATION E2E UNIT

  96. 16 – 17 November, Sofia ISTACON.ORG Complex logic Business rules

    Protecting invariants Domain Model
  97. 16 – 17 November, Sofia ISTACON.ORG public class User {

    public Guid Id { get; private set; }
 public string Name { get; private set; }
 public List<Interest> Interests { get; private set; }
 public Address Address { get; private set; } public void UpdateDetails() { … }
 public void AddInterest() { … }
 public static User InitializeNew() { … } }
  98. 16 – 17 November, Sofia ISTACON.ORG E2E INTEGRATION UNIT

  99. 16 – 17 November, Sofia ISTACON.ORG Adjustment #2: Testing Strategies

  100. 16 – 17 November, Sofia ISTACON.ORG • Transaction Script -

    100% End to end Adjustment #2: Testing Strategies
  101. 16 – 17 November, Sofia ISTACON.ORG • Transaction Script -

    100% End to end • Active Record - 100% Integration tests Adjustment #2: Testing Strategies
  102. 16 – 17 November, Sofia ISTACON.ORG • Transaction Script -

    100% End to end • Active Record - 100% Integration tests • Domain Model - 100% Unit tests Adjustment #2: Testing Strategies
  103. 16 – 17 November, Sofia ISTACON.ORG Design?

  104. 16 – 17 November, Sofia ISTACON.ORG Well designed code is

    testable
  105. 16 – 17 November, Sofia ISTACON.ORG Well designed code is

    testable Testable code is well designed
  106. 16 – 17 November, Sofia ISTACON.ORG Well designed code is

    testable Testable code is well designed
  107. 16 – 17 November, Sofia ISTACON.ORG Transaction Script Active Record

    Domain Model Business Logic Modeling Patterns
  108. 16 – 17 November, Sofia ISTACON.ORG • System’s design is

    driven by its business domain, its needs and its problems • Development can be driven by tests Adjustment #3: Design vs. Development
  109. 16 – 17 November, Sofia ISTACON.ORG • System’s design is

    driven by its business domain, its needs and its problems • Development can be driven by tests • Test-Driven Design • Test-Driven Development Adjustment #3: Design vs. Development
  110. 16 – 17 November, Sofia ISTACON.ORG Taking Care of Tests

  111. 16 – 17 November, Sofia ISTACON.ORG

  112. 16 – 17 November, Sofia ISTACON.ORG AUTOMATED TESTS ARE PRODUCTION

    CODE
  113. 16 – 17 November, Sofia ISTACON.ORG [TestMethod] public void SetAsUnqualified_ClearWeights()

    { var lead = BuildLead(10, 15, 24, false); lead.SetAsUnqualified(updatedContactDetails, policy, 12); Assert.AreEqual(12, lead.Proprity); }
  114. 16 – 17 November, Sofia ISTACON.ORG [TestMethod] public void SetAsUnqualified_ClearWeights()

    { var lead = BuildLead(10, 15, 24, false); lead.SetAsUnqualified(updatedContactDetails, policy, 12); Assert.AreEqual(12, lead.Proprity); }
  115. 16 – 17 November, Sofia ISTACON.ORG [TestMethod] public void SetAsUnqualified_ClearWeights()

    { var lead = BuildLead(someUserId, groupId, events, notNew); lead.SetAsUnqualified(updatedContactDetails, policy, agentId); Assert.AreEqual(newLeadPriority, lead.Proprity); }
  116. 16 – 17 November, Sofia ISTACON.ORG [TestMethod] public void CreateLeadActivity_CreateValidJSON()

    { var depositActivity = new DepositActivity(); depositActivity.ActivityTypeId = 6002; depositActivity.AdvertiserActivityTypeId = 3; depositActivity.ActivityDescription = "Deposit-Approved"; depositActivity.AdvertiserId = 1; depositActivity.AgencyId = 23; depositActivity.BrandId = 1; depositActivity.CustomerId = "eyookon93@yahoo.com"; depositActivity.CreatedDate = new DateTime(2015, 03, 23, 9, 30, 42); depositActivity.Domain = "deposit.23traders.com"; depositActivity.LabelId = 1; depositActivity.TransactionId = 25; depositActivity.CreatedDateStr = "2015-03-23T09:30:42+00:00"; var leadActivityDTo = new LeadActivityDTO(depositActivity, false); var serializeObject = new JsonNetAdapter().SerializeObject(leadActivityDTo); A.CallTo(() => jsonSerializer.SerializeObject(leadActivityDTo)).WithAnyArguments().Returns(serializeObject); var result = new DepositActivityFactory(jsonSerializer).CreateLeadActivity(depositActivity); Assert.AreEqual(result, leadActivityJSON); }
  117. 16 – 17 November, Sofia ISTACON.ORG Gherkin Language • Given

    • When • Then
  118. 16 – 17 November, Sofia ISTACON.ORG [TestMethod] public void CreateLeadActivity_CreateValidJSON()

    { var depositActivity = new DepositActivity(); depositActivity.ActivityTypeId = 6002; depositActivity.AdvertiserActivityTypeId = 3; depositActivity.ActivityDescription = "Deposit-Approved"; depositActivity.AdvertiserId = 1; depositActivity.AgencyId = 23; depositActivity.BrandId = 1; depositActivity.CustomerId = "eyookon93@yahoo.com"; depositActivity.CreatedDate = new DateTime(2015, 03, 23, 9, 30, 42); depositActivity.Domain = "deposit.23traders.com"; depositActivity.LabelId = 1; depositActivity.TransactionId = 25; depositActivity.CreatedDateStr = "2015-03-23T09:30:42+00:00"; var leadActivityDTo = new LeadActivityDTO(depositActivity, false); var serializeObject = new JsonNetAdapter().SerializeObject(leadActivityDTo); A.CallTo(() => jsonSerializer.SerializeObject(leadActivityDTo)).WithAnyArguments().Returns(serializeObject); var result = new DepositActivityFactory(jsonSerializer).CreateLeadActivity(depositActivity); Assert.AreEqual(result, leadActivityJSON); }
  119. 16 – 17 November, Sofia ISTACON.ORG Scenario: Check monthly report

    Given today is 2015/05/18 And a payment was made for the 2015/04 period on 2015/04/01 When we generate agent's monthly report for 2015/03 Then payment log cannot be generated And the payment log was generated on 2015/04/01
  120. 16 – 17 November, Sofia ISTACON.ORG Jasmine (JavaScript) SpecFlow (.Net)

    Behave (Python) Cucumber (Ruby) etc
  121. 16 – 17 November, Sofia ISTACON.ORG Examples

  122. 16 – 17 November, Sofia ISTACON.ORG public virtual void SetAsConverted(…)

    { UpdateContactDetails(updatedContactDetails.Name); var waitDaysForDeposit = Settings.GetAppConfigInt("Days"); ClearWeights(); TrackPhoneCall(phoneNumber, convertedBy, convertedOn); ResetInteraction(); UpdateModifiedByAndOn(convertedBy.Id, convertedOn); Apply(new DepositPending(State.Id, interactionId)); } C.Complexity: Low or High?
  123. 16 – 17 November, Sofia ISTACON.ORG public virtual void SetAsConverted(…)

    { UpdateContactDetails(updatedContactDetails.Name); var waitDaysForDeposit = Settings.GetAppConfigInt("Days"); ClearWeights(); TrackPhoneCall(phoneNumber, convertedBy, convertedOn); ResetInteraction(); UpdateModifiedByAndOn(convertedBy.Id, convertedOn); Apply(new DepositPending(State.Id, interactionId)); } Unit Test or Integration Test?
  124. 16 – 17 November, Sofia ISTACON.ORG Active Record or Domain

    Model? You are working on a CRM system, and you are asked to build a service that calculates commissions for sales agents. There about 100 different commissions rules, and managers should be able to optimize them on the fly.
  125. 16 – 17 November, Sofia ISTACON.ORG Full Coverage by Unit

    or Integration Tests? You are asked to build a service that calculates commissions for sales agents. There are about 100 different commissions rules, and managers should be able to optimize them on the fly.
  126. 16 – 17 November, Sofia ISTACON.ORG Active Record or Domain

    Model?
  127. 16 – 17 November, Sofia ISTACON.ORG Full Coverage by Integration

    or Unit Tests?
  128. 16 – 17 November, Sofia ISTACON.ORG Summary

  129. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Simplest design • Isolate the Class under test • Refactor • Repeat • 100% unit test coverage • Maintainable and extendable code • FAST!!! Fakes Mocks Stubs TEST-DRIVEN DESIGN
  130. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Simplest design • Refactor • Repeat • 100% unit test coverage • FAST!!! Fakes Mocks Stubs TEST-DRIVEN DESIGN • Isolate the Class under test • Maintainable and extendable code
  131. 16 – 17 November, Sofia ISTACON.ORG • Write a failing

    Unit Test • Write code to a make it pass • Simplest design • Refactor • Repeat • 100% unit test coverage • FAST!!! TEST-DRIVEN DESIGN
  132. 16 – 17 November, Sofia ISTACON.ORG • Write code to

    a make it pass • Simplest design • Refactor • Repeat • FAST!!! TEST-DRIVEN DESIGN • Write a failing Unit Test • 100% unit test coverage
  133. 16 – 17 November, Sofia ISTACON.ORG • Write code to

    a make it pass • Simplest design • Refactor • Repeat • FAST!!! TEST-DRIVEN DESIGN • 100% unit test coverage
  134. 16 – 17 November, Sofia ISTACON.ORG • Write code to

    a make it pass • Simplest design • Refactor • Repeat • FAST!!! TEST-DRIVEN DESIGN
  135. 16 – 17 November, Sofia ISTACON.ORG • Write code to

    a make it pass • Simplest design • Refactor • Repeat • FAST!!! TEST-DRIVEN DESIGN
  136. 16 – 17 November, Sofia ISTACON.ORG • Write code to

    a make it pass
 • Repeat
 
 
 TEST-DRIVEN • Simplest design • Refactor • Fast DESIGN
  137. 16 – 17 November, Sofia ISTACON.ORG • Write code to

    a make it pass
 • Repeat
 
 
 TEST-DRIVEN • Refactor • Fast DESIGN
  138. 16 – 17 November, Sofia ISTACON.ORG • Write code to

    a make it pass
 • Repeat
 
 
 TEST-DRIVEN • Fast DESIGN
  139. 16 – 17 November, Sofia ISTACON.ORG • Write code to

    a make it pass
 • Repeat
 
 
 TEST-DRIVEN DESIGN
  140. 16 – 17 November, Sofia ISTACON.ORG • Write code to

    a make it pass
 • Repeat
 
 
 TEST-DRIVEN
  141. 16 – 17 November, Sofia ISTACON.ORG TDD Rebooted

  142. 16 – 17 November, Sofia ISTACON.ORG TEST-DRIVEN DEVELOPMENT

  143. 16 – 17 November, Sofia ISTACON.ORG • Learn the business

    domain • Analyze • Assess its complexity TEST-DRIVEN DEVELOPMENT
  144. 16 – 17 November, Sofia ISTACON.ORG • Learn the business

    domain • Analyze • Assess its complexity • Design the solution • Business logic modeling pattern • Testing strategy TEST-DRIVEN DEVELOPMENT
  145. 16 – 17 November, Sofia ISTACON.ORG • Learn the business

    domain • Analyze • Assess its complexity • Design the solution • Business logic modeling pattern • Testing strategy • Development • Start with a failing test (according to the testing strategy) • Make it pass • Refactor TEST-DRIVEN DEVELOPMENT
  146. 16 – 17 November, Sofia ISTACON.ORG P.S.

  147. 16 – 17 November, Sofia ISTACON.ORG

  148. 16 – 17 November, Sofia ISTACON.ORG Thank you! @vladikk vladikk.com

    Vladik Khononov vladik@khononov.com