Slide 1

Slide 1 text

Fix my TDD Patterns for efficient Tests

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Christian Fischer TDD in a Nutshell Test Implementation Refactoring

Slide 4

Slide 4 text

Christian Fischer Simple, but not easy

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

Christian Fischer Test Storming • Swarm Intelligence • Time boxing • Integration in Refinement and Planning or 3-Amigo-Session

Slide 8

Slide 8 text

Christian Fischer Test Path • from simple to complex • start with happy path • use git to rewind

Slide 9

Slide 9 text

Christian Fischer ZOMBIES Simple Scenarios Simple Solutions Zero One Many Boundaries Behavior Interfaces Exercise Exceptions from James Grenning

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

Christian Fischer TDD Tip #1 Always start with an ordered test list.

Slide 12

Slide 12 text

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[]

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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]

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

Christian Fischer Leaky Refactoring Refactoring: Split name into two fields.

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

Christian Fischer In a galaxy (not so) far far away

Slide 21

Slide 21 text

Christian Fischer Problems • Fixating Design & Framework • Testing implementation, not Behaviour • Speculating about 3rd party behaviour

Slide 22

Slide 22 text

Christian Fischer The golden Rule ONLY MOCK TYPES THAT YOU OWN from „Growing Object Oriented Design, guided by Tests [Steve Freeman, Nat Pryce]

Slide 23

Slide 23 text

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?

Slide 24

Slide 24 text

Christian Fischer Two Component Types … • Input/Output • Side Effects • Nonfunctional driven • deterministic • Business Logic • feature driven T echnical L ogical

Slide 25

Slide 25 text

Christian Fischer Unit Test L ogical § Repeatable § Consistent § In Memory § Fast § Single Concern Unit Test is ... from Roy Osherove: The art of Unit Testing

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Christian Fischer Design with CRC Cards Component Reponsibility Collaborators should… • …… • …… • …… calls… • …… • …… • …… from Kent Beck

Slide 28

Slide 28 text

Christian Fischer TDD Tip #3 Write Adapters for Integration Code and mock these.

Slide 29

Slide 29 text

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.

Slide 30

Slide 30 text

Christian Fischer no Multi- Tasking Protection from Overengineering Complexity Partitioning no Fear of Change zero Debug Time Testable Design TDD Benefits TDD

Slide 31

Slide 31 text

Mehr zu TDD: @agiledojo https://agiledojo.de