Fix my TDD Patterns for efficient Tests
TDD in a Nutshell Test Christian Fischer Refactoring Implementation
Simple, but not easy Christian Fischer
Password Validator Kata boolean validate(String password) A password it valid, when it has • at least 6 characters Christian Fischer • at least one upper case letter • at least one lower case letter • at least one special character
The Test List Valid password 1 Analyse the problem „ aBc_de -> true Less than minimum characters „ aBc_de “ -> false find simple examples Christian Fischer 2 No upper case for each equivalence class „ ab_cde “ -> false No lower case add to list any time, 3 „ABC_DE“ -> false but don‘t interrrupt cycle No special character „ aBcxde “ -> false from Kent Beck
Test Storming • Swarm Intelligence • Time boxing Christian Fischer • Integration in Refinement and Planning or 3-Amigo-Session
Test Path • from simple to complex • start with happy path Christian Fischer • use git to rewind
ZOMBIES Z ero S imple Scenarios O ne S imple Solutions Christian Fischer M any B oundaries Exercise I nterfaces Behavior E xceptions from James Grenning
Transformation Priority Premise {} --> nil simple nil --> constant constant --> constant+ constant --> scalar statement --> statements unconditional --> if Christian Fischer scalar --> array array --> container statement --> recursion if --> while expression --> function variable --> assignment complex from Robert C. Martin
TDD Tip #1 Christian Fischer Always start with an ordered test list.
Query Parser Kata QueryParser QueryParserTest „ guitar “ -> [guitar] + parse(String query): String[] “ red electric guitar “ -> [red, electric, guitar] Christian Fischer „ red guitar with gigbag “ -> [red,guitar,gigback] - removeStopwords(String[] words) : String[] „ red guitar and gigbag “ -> [red,guitar,gigback] - removeNumbers(String[] words) : String[] „ red guitar with 7 gigbag “ -> [red,guitar,gigback]
Query Parser Kata QueryParserTest QueryParser -setUpMocks / MockInteractionTest + QueryParser(filter: QueryFilter) „ guitar “ -> [guitar] + parse(query: String): String [] “ red electric guitar “ -> [red, electric, guitar] QueryFilter QueryFilterTest + filter(words: String[]): String[] [red,guitar,with,gigback]-> [red,guitar,gigback] Christian Fischer - removeStopwords(words: String[]) : String[] [red,guitar,and,gigback] -> [red,guitar,gigback] [red,guitar,7,gigback] -> [red,guitar,gigback] - removeNumbers(words: String[]) : String[
Query Parser Kata QueryParserTest QueryParser -setUpMocks + QueryParser(filter: QueryParser) „ guitar “ -> [guitar] + parse(query: String) “ red electric guitar “ -> [red, electric, guitar] - toLowerCase(word: String) : String „Guitar“ -> [guitar] - toSingular(word: String) : String “ guitars “ -> [guitar] QueryFilter Christian Fischer QueryFilterTest + filter(words: String[]): String[] [red,guitar,with,gigback]-> [red,guitar,gigback] - removeStopwords(words: String[]) : Stri [red,guitar,and,gigback] -> [red,guitar,gigback] [red,guitar,7,gigback] -> [red,guitar,gigback] - removeNumbers(words: String[]) : String[
Query Parser Kata QueryParserTest QueryParser -setUpMocks / MockInteractionTest + QueryParser(filter: QueryFilter, normalizer: QueryNormalizer) „ guitar “ -> [guitar] “ red electric guitar “ -> [red, electric, guitar] + parse(query: String) QueryFilter QueryFilterTest + filter(words: String[]): String[] Christian Fischer [red,guitar,with,gigback]-> [red,guitar,gigback] - removeStopwords(words: String[]) : Stri [red,guitar,and,gigback] -> [red,guitar,gigback] [red,guitar,7,gigback] -> [red,guitar,gigback] - removeNumbers(words: String[]) : String[ QueryNormalizerTest QueryNormalizer + normalize(word: String): String „Guitar“ -> „ guitar “ - toLowerCase(word: String) : String „ guitars “ -> „ guitar “ - toSingular(word: String) : String
Strong Coupling package private Class public Class Parser Tests Parser Module QueryParser QueryParserTest Christian Fischer QueryFilter QueryFilterTest QueryNormalizerTest QueryNormalizer
Loose Coupling package private Class public Class Parser Tests Parser Module QueryParserTest QueryParser Christian Fischer QueryFilterTest QueryFilter QueryNormalizerTest QueryNormalizer
Leaky Refactoring Refactoring: Split name into two fields. Christian Fischer
TDD Tip #2 Christian Fischer Develop your Tests against the Module API.
In a galaxy (not so) far far away Christian Fischer
Problems • Fixating Design & Framework • Testing implementation, not Behaviour • Speculating about 3rd party behaviour Christian Fischer
The golden Rule ONLY MOCK TYPES THAT YOU OWN from „ Growing Object Oriented Design, guided by Tests [Steve Freeman, Nat Pryce] Christian Fischer
Weak Unit Tests Does the Endpoint has the corrrect Path & Method? Does the Deserialization works as expected? Christian Fischer Does the Serialization works as expected?
Two Component Types … T echnical L ogical Christian Fischer • Input/Output • deterministic • Business Logic • Side Effects • Nonfunctional driven • feature driven
Unit Test Unit Test is ... ▪ Repeatable ▪ Consistent L ogical ▪ In Memory Christian Fischer ▪ Fast ▪ Single Concern from Roy Osherove: The art of Unit Testing
Integration Test Integration Test may ... ▪ Use system dependent variables ▪ Create object with little Control T echnical Christian Fischer (e.g. Threads, etc.) ▪ Reach out to external systems ▪ Test several components from Roy Osherove: The art of Unit Testing
Design with CRC Cards Component Reponsibility Collaborators should … calls … Christian Fischer • …… • …… • …… • …… • …… • …… from Kent Beck
TDD Tip #3 Christian Fischer Write Adapters for Integration Code and mock these.
5 Rules for efficient and effective TDD 1 Develop your Tests against the Module API. 2 Test the Behaviour, not the Implementation. 3 Don‘t mock external libraries, use Adapters. Christian Fischer 4 Use Integration Tests for I/O-Components. 5 Make a Test Plan.
TDD Benefits Protection from Overengineering no Fear Complexity of Change Partitioning TDD Christian Fischer zero Debug no Multi- Time Tasking Testable Design
Mehr zu TDD: @agiledojo https://agiledojo.de
Recommend
More recommend