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

Fix my TDD - Patterns for effective Tests

Fix my TDD - Patterns for effective Tests

How to avoid common pitfalls when starting with TDD and to efficiently and effectively test drive your product.

7379c719bba185bb01143b61b84c373d?s=128

Christian Fischer

February 20, 2020
Tweet

Transcript

  1. Fix my TDD Patterns for efficient Tests

  2. Christian Fischer Software Engineering Coach http://agiledojo.de @agiledojo

  3. Christian Fischer TDD in a Nutshell Test Implementation Refactoring

  4. Christian Fischer Simple, but not easy

  5. Christian Fischer Password Validator Kata boolean validate(String password) A password

    it valid, when it has • at least 6 characters • at least one upper case letter • at least one lower case letter • at least one special character
  6. Christian Fischer The Test List Valid password „aBc_de -> true

    Less than minimum characters „aBc_de“ -> false No upper case „ab_cde“ -> false No lower case „ABC_DE“ -> false No special character „aBcxde“ -> false 1 Analyse the problem 2 find simple examples for each equivalence class 3 add to list any time, but don‘t interrrupt cycle from Kent Beck
  7. Christian Fischer Test Storming • Swarm Intelligence • Time boxing

    • Integration in Refinement and Planning or 3-Amigo-Session
  8. Christian Fischer Test Path • from simple to complex •

    start with happy path • use git to rewind
  9. Christian Fischer ZOMBIES Simple Scenarios Simple Solutions Zero One Many

    Boundaries Behavior Interfaces Exercise Exceptions from James Grenning
  10. Christian Fischer Transformation Priority Premise {} --> nil nil -->

    constant constant --> constant+ constant --> scalar statement --> statements unconditional --> if scalar --> array array --> container statement --> recursion if --> while expression --> function variable --> assignment simple complex from Robert C. Martin
  11. Christian Fischer TDD Tip #1 Always start with an ordered

    test list.
  12. Christian Fischer QueryParserTest Query Parser Kata „guitar“ -> [guitar] “red

    electric guitar“ -> [red, electric, guitar] „red guitar with gigbag“ -> [red,guitar,gigback] „red guitar and gigbag“ -> [red,guitar,gigback] QueryParser + parse(String query): String[] - removeStopwords(String[] words) : String[] „red guitar with 7 gigbag“ -> [red,guitar,gigback] - removeNumbers(String[] words) : String[]
  13. Christian Fischer QueryFilter QueryFilterTest QueryParserTest Query Parser Kata „guitar“ ->

    [guitar] “red electric guitar“ -> [red, electric, guitar] [red,guitar,with,gigback]-> [red,guitar,gigback] [red,guitar,and,gigback] -> [red,guitar,gigback] QueryParser + parse(query: String): String [] - removeStopwords(words: String[]) : String[] [red,guitar,7,gigback] -> [red,guitar,gigback] - removeNumbers(words: String[]) : String[] + filter(words: String[]): String[] + QueryParser(filter: QueryFilter) -setUpMocks / MockInteractionTest
  14. Christian Fischer QueryFilter QueryFilterTest QueryParserTest Query Parser Kata „guitar“ ->

    [guitar] “red electric guitar“ -> [red, electric, guitar] [red,guitar,with,gigback]-> [red,guitar,gigback] [red,guitar,and,gigback] -> [red,guitar,gigback] QueryParser + parse(query: String) - removeStopwords(words: String[]) : String[] [red,guitar,7,gigback] -> [red,guitar,gigback] - removeNumbers(words: String[]) : String[] + filter(words: String[]): String[] + QueryParser(filter: QueryParser) -setUpMocks „Guitar“ -> [guitar] - toLowerCase(word: String) : String - toSingular(word: String) : String “guitars“ -> [guitar]
  15. Christian Fischer QueryFilter QueryFilterTest QueryParserTest Query Parser Kata „guitar“ ->

    [guitar] “red electric guitar“ -> [red, electric, guitar] [red,guitar,with,gigback]-> [red,guitar,gigback] [red,guitar,and,gigback] -> [red,guitar,gigback] QueryParser + parse(query: String) - removeStopwords(words: String[]) : String[] [red,guitar,7,gigback] -> [red,guitar,gigback] - removeNumbers(words: String[]) : String[] + filter(words: String[]): String[] + QueryParser(filter: QueryFilter, normalizer: QueryNormalizer) -setUpMocks / MockInteractionTest QueryNormalizerTest „Guitar“ -> „guitar“ „guitars“ -> „guitar“ QueryNormalizer + normalize(word: String): String - toLowerCase(word: String) : String - toSingular(word: String) : String
  16. Christian Fischer Strong Coupling Parser Module QueryParser QueryFilter QueryNormalizer QueryParserTest

    Parser Tests QueryFilterTest QueryNormalizerTest public Class package private Class
  17. Christian Fischer Loose Coupling Parser Module QueryParser QueryFilter QueryNormalizer QueryParserTest

    Parser Tests QueryFilterTest QueryNormalizerTest public Class package private Class
  18. Christian Fischer Leaky Refactoring Refactoring: Split name into two fields.

  19. Christian Fischer TDD Tip #2 Develop your Tests against the

    Module API.
  20. Christian Fischer In a galaxy (not so) far far away

  21. Christian Fischer Problems • Fixating Design & Framework • Testing

    implementation, not Behaviour • Speculating about 3rd party behaviour
  22. Christian Fischer The golden Rule ONLY MOCK TYPES THAT YOU

    OWN from „Growing Object Oriented Design, guided by Tests [Steve Freeman, Nat Pryce]
  23. Christian Fischer Weak Unit Tests Does the Endpoint has the

    corrrect Path & Method? Does the Deserialization works as expected? Does the Serialization works as expected?
  24. Christian Fischer Two Component Types … • Input/Output • Side

    Effects • Nonfunctional driven • deterministic • Business Logic • feature driven T echnical L ogical
  25. Christian Fischer Unit Test L ogical § Repeatable § Consistent

    § In Memory § Fast § Single Concern Unit Test is ... from Roy Osherove: The art of Unit Testing
  26. Christian Fischer Integration Test T echnical § Use system dependent

    variables § Create object with little Control (e.g. Threads, etc.) § Reach out to external systems § Test several components Integration Test may ... from Roy Osherove: The art of Unit Testing
  27. Christian Fischer Design with CRC Cards Component Reponsibility Collaborators should…

    • …… • …… • …… calls… • …… • …… • …… from Kent Beck
  28. Christian Fischer TDD Tip #3 Write Adapters for Integration Code

    and mock these.
  29. Christian Fischer 5 Rules for efficient and effective TDD 1

    Develop your Tests against the Module API. 2 Test the Behaviour, not the Implementation. 4 Use Integration Tests for I/O-Components. 3 Don‘t mock external libraries, use Adapters. 5 Make a Test Plan.
  30. Christian Fischer no Multi- Tasking Protection from Overengineering Complexity Partitioning

    no Fear of Change zero Debug Time Testable Design TDD Benefits TDD
  31. Mehr zu TDD: @agiledojo https://agiledojo.de