SlideShare ist ein Scribd-Unternehmen logo
1 von 84
Downloaden Sie, um offline zu lesen
TDD As If You Meant It
Alex Bolboacă,  @alexboly,  alex.bolboaca@mozaicworks.com
October 2017
Test Driven Development
TDD As If You Meant It
A Simple Example
Practising TDD As If You Meant It
Applying TDD As If You Meant It in Production
Closing
Test Driven Development
Like Brewing Coffee
TDD is like brewing coffee
My Definition
A process for designing software incrementally by clarifying the problem
before the solution, and allowing the solution to appear from the tension
between tests and existing code.
Emergent design
The design is an emergent property because it appears from a combination
of properties of programmer, test code and production code.
So, …
When doing “pure” TDD, you shouldn’t start with any preconceived ideas
about the solution
But…
Most of the time we fail at this rule
Goal
The goal is not to ignore your past experience.
The goal is to allow yourself to gather more experiences.
TDD As If You Meant It
What Is It?
A set of constraints that force the practise of “pure” TDD.
Constraints
You are not allowed to create any:
• named constant
• variable
• method
• class
other than by refactoring it out of a test.
Constraints
All production code is first written in tests and then extracted through
refactoring
A Simple Example
We Need A Problem
Bank account kata
Think of your personal bank account experience. When in doubt, go for the
simplest solution.
Requirements
• Deposit and Withdrawal
• Transfer
• Account statement (date, amount, balance)
• Statement printing
• Statement filters (just deposits, withdrawal, date)
Source: https://github.com/sandromancuso/Bank-kata/
Technology
I’ll use groovy and spock
First test
def ”the first test”(){
expect:
false
}
Isn’t this beautiful?
Let’s take the time to properly admire the serenity and simplicity of this test ⌣
First weird question
What is false?
False in programming
In logic, false is a truth value associated to an assertion.
In programming false is either a constant or the result of a boolean
operation.
So what is false?
def ”after a deposit of €5 in an empty account 
its balance is €5”{
expect:
424532534 == 5
}
Make the first test pass
def ”after a deposit of €5 in an empty account 
its balance is €5”{
expect:
0 + 5 == 5
}
Celebrate!
Yay!
Refactor
Remember We’re only allowed to:
• extract constant
• extract variable
• remove duplication
The test needs more clarity
0 + 5 == 5
What is 5? What is 0?
• 0: initial account balance
• first 5: deposit amount
• second 5: final account balance
 Accidental duplication!
Clarity
def ”after a deposit of €5 in an empty account 
its balance is €5”{
given:
def expectedFinalBalance = 5
def initialBalance = 0
def amount = 5
when:
def finalBalance = initialBalance + amount
then:
finalBalance == expectedFinalBalance
}
Notions …
Let’s take a look at the notions we’re using:
• deposit amount
• empty account
• balance
• initial balance
• final balance
Semantics
Empty account = account that has an initial balance of 0
 Duplication!
Express it!
def ”after depositing €5 in an account with balance 0 
its balance is €5”{
given:
def expectedFinalBalance = 5
def initialBalance = 0
def amount = 5
when: // Production code
def finalBalance = initialBalance + amount
then:
finalBalance == expectedFinalBalance
}
Next test?
Triangulation: the process of writing another test that changes a single
input from the input set with the goal of advancing towards the solution
Triangulation - Advanced
We triangulate in the topology of possible solutions
What can we triangulate on?
• initial balance
• deposit amount
• currency (€, RON, £)
• account (eg. ownership, type of account etc.)
Decision
Let’s triangulate on deposit
What are interesting values for deposit?
Value sampling or Equivalence partitioning
Since we cannot test all the values, find the intervals that are interesting
and pick at least one value from each interval
Equivalence partitioning for deposit
• Negative numbers: e.g. -€1, -€5
• Zero
• Positive numbers
• Minimum ?
• Maximum ?
• Non-integers: e.g. €1.50, €99.99
Questions, questions…
Can an account have negative balance? Yes
Can we deposit a negative amount? No
What’s the maximum amount in an account? Use €1.000.000.000
What’s the minimum amount in an account? Use -€10.000
What’s the minimum deposit? Use €1
What’s the maximum deposit? Use €1.000.000.000
So, triangulation on deposit
Accepted values:
• Minimum: €1
• Any value between €1 and €1.000.000.000
• Maximum: €1.000.000.000 (in an account with 0)
Invalid values:
• Less than minimum: €0.99
• More than maximum: €1.000.000.000,01
Second test
def ”after a deposit of €1 in an account with balance 0 
its balance is €1”{
expect:
false
}
What is false?
def ”after a deposit of €1 in an account with balance 0
its balance is €1”{
expect:
1 == 0 + 241234123423
}
Make it pass
def ”after a deposit of €1 in an account with balance 0
its balance is €1”{
expect:
1 == 0 + 1
}
Refactor to clarify
def ”after a deposit of €1 in an account with balance 0
its balance is €1”{
given:
def initialBalance = 0
def amount = 1
def expectedFinalBalance = 1
when: //Production code
def finalBalance = initialBalance + amount
then:
expectedFinalBalance == finalBalance
}
More refactoring?
Duplication between tests!
Rule of three
Rule of Three
 Remove duplication after you’ve seen it for 3 or more times
So, next test
def ”after a deposit of €1.000.000.000 in an account
with balance 0 its balance is €1.000.000.000”{
expect:
false
}
5 minutes later …
def ”after a deposit of €1.000.000.000 in an account
with balance 0 its balance is €1.000.000.000”{
given:
def initialBalance = 0
def amount = 1000000000
def expectedFinalBalance = 1000000000
when: //Production code
def finalBalance = initialBalance + amount
then:
expectedFinalBalance == finalBalance
}
Anything else to refactor?
Q: What is 1.000.000.000?
A: Maximum balance for an account in € is €1.000.000.000.
Extract max balance
static final maxBalance = 1000000000
def ”after a deposit of #maxBalance in an account
with balance 0 its balance is #maxBalance”{
given:
def initialBalance = 0
def amount = maxBalance
def expectedFinalBalance = maxBalance
when: //Production code
def finalBalance = initialBalance + amount
then:
expectedFinalBalance == finalBalance
}
How to Remove Duplication?
Two options:
• remove duplication from tests using data driven tests
• remove duplication from production code using a method
Data driven tests?
def ”after a deposit of #amount in an account
with balance #balance
its balance is #expectedFinalBalance”{
when: ”deposit”
def finalBalance = initialBalance + amount
then:
expectedFinalBalance == finalBalance
where:
initialBalance | amount || expectedFinalBalance
0 | 1 || 1
0 | 5 || 5
0 | maxBalance || maxBalance
Hmm…
 Feels like it doesn’t advance the solution
Spoiler: I’ll come back to this later
Extract production code
def deposit(initialBalance, amount){
return initialBalance + amount
}
Reflection time
How’s it going?
Let’s reflect
• We didn’t write a lot of code: three tests and one line of production
code
• We learned a lot about the domain
• We learned a lot about the business rules
• We named things
• We have the simplest solution to the problem so far
• It feels slow
Most importantly
We can see how the code evolves: constant -> variable -> method
Let’s Look Into The Future: Deposit
static final maxBalance = 1000000000
def deposit(amount, initialBalance){
if(amount < 1)
return initialBalance
if(initialBalance + amount > maxBalance)
return initialBalance
return initialBalance + amount
}
Let’s Look Into The Future: Withdrawal
static final minBalance = -50000
def withdraw(amount, initialBalance){
if(amount < 1)
return initialBalance
if(initialBalance - amount < minBalance)
return initialBalance
return initialBalance - amount
}
We have a design choice
Go functional or go Object Oriented
Functional solution
def balance = deposit(10,
withdraw(200,
withdraw(500,
withdraw(10,
deposit(1000, /*initialBalance*/ 0)))))
Object Oriented Solution
def account = new Account(balance: 0)
account.deposit(1000)
account.withdraw(10)
account.withdraw(500)
account.withdraw(200)
account.deposit(10)
def balance = account.balance
Different Object Oriented Solution
def account = new Account(balance: 0)
def transactions = [
new DepositTransaction(amount: 1000),
new WithdrawalTransaction(amount: 10),
new WithdrawalTransaction(amount: 500),
new WithdrawalTransaction(amount: 200),
new DepositTransaction(amount: 10)
]
account.applyTransactions(transactions)
def balance = account.balance
What’s the difference?
A class is nothing more than a set of cohesive, partially applied pure
functions
– via JB Rainsberger
Partially applied function
account.deposit(amount)
is a partial application of:
deposit(amount, initialBalance)
And now for something completely different…
Pssst… Huge Monty Python fan here
Let’s rewind …
def ”after a deposit of #deposit in an account
with balance 0
its balance is #deposit”{
when: ”deposit”
def finalBalance = initialBalance + amount
then:
expectedFinalBalance == finalBalance
where:
initialBalance | amount || expectedFinalBalance
0 | 1 || 1
0 | 5 || 5
0 | maxBalance || maxBalance
And reinterpret this
Whenever we deposit a deposit amount less or equal to the maximum
balance into an account that has initial balance 0, the resulting balance is
the deposit amount
 Property based testing
Spock Genesis
spock-genesis library
https://github.com/Bijnagte/spock-genesis
A library that helps generating values for properties
A property based test
def ”after a deposit in an account
with balance 0
its balance is the deposit amount”{
when: ”deposit”
def finalBalance = deposit(amount,
initialBalance)
then:
expectedFinalBalance == finalBalance
where:
amount << integer(1..maxBalance).take(500)
initialBalance = 0
expectedFinalBalance = amount
Reflection time
• We’ve learned more about software design
• We’ve learned more about testing
• We left our options open until we picked functional or OO approach
• We decided step by step what’s the right next step
• Still feels slow
Practising TDD As If You Meant It
How
• Pick any kata, or a pet project
• Set up a timer at 45’
• Do it every day for 10 days (continue where you left off)
• Reflect on the way the design evolves, and on the design options you
took
•  Make every decision as deliberate as possible
Applying TDD As If You Meant It in
Production
Do It Like Mythbusters
Mythbusters
How?
• Separate a small(ish) problem. Eg: special alerts in a web application,
validation in client-side code, a UI control etc.
How?
• Separate a small(ish) problem. Eg: special alerts in a web application,
validation in client-side code, a UI control etc.
• Start a new test suite (maybe even a new project)
How?
• Separate a small(ish) problem. Eg: special alerts in a web application,
validation in client-side code, a UI control etc.
• Start a new test suite (maybe even a new project)
• Write the implementation using TDD as If You Meant It
How?
• Separate a small(ish) problem. Eg: special alerts in a web application,
validation in client-side code, a UI control etc.
• Start a new test suite (maybe even a new project)
• Write the implementation using TDD as If You Meant It
• When you have the production code, integrate it with the rest of the
code
Closing
Conclusions
TDD As If You Meant It has helped me become more deliberate about
software design.
• Despite feeling slow, I found it is quite fast after practising
Conclusions
TDD As If You Meant It has helped me become more deliberate about
software design.
• Despite feeling slow, I found it is quite fast after practising
• It helped me understand more about functional programming
Conclusions
TDD As If You Meant It has helped me become more deliberate about
software design.
• Despite feeling slow, I found it is quite fast after practising
• It helped me understand more about functional programming
• The feeling of working on a small, clean, piece of code instead of the
“big” code is very liberating
My advice
Embrace constraints
“I have never been forced to accept compromises but I
have willingly accepted constraints”
Charles Eames, Designer and Architect
Learn more
Adi’s Blog http://blog.adrianbolboaca.ro
Thank you!
I’ve been Alex Bolboacă, @alexboly, alex.bolboaca@mozaicworks.com
programmer, trainer, mentor, writer
at Mozaic Works
Think. Design. Work Smart.
https://mozaicworks.com
Q&A
Q&A

Weitere ähnliche Inhalte

Ähnlich wie TDD As If You Meant It

Por qué usar Spock en lugar de JUnit / Mockito para tus tests Java - Codemoti...
Por qué usar Spock en lugar de JUnit / Mockito para tus tests Java - Codemoti...Por qué usar Spock en lugar de JUnit / Mockito para tus tests Java - Codemoti...
Por qué usar Spock en lugar de JUnit / Mockito para tus tests Java - Codemoti...Andrés Viedma Peláez
 
Domain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with RailsDomain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with RailsDeclan Whelan
 
CSC139 Chapter 9 Lab Assignments (1) Classes and Obj.docx
CSC139 Chapter 9 Lab Assignments (1) Classes and Obj.docxCSC139 Chapter 9 Lab Assignments (1) Classes and Obj.docx
CSC139 Chapter 9 Lab Assignments (1) Classes and Obj.docxruthannemcmullen
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test communityKerry Buckley
 
The Ring programming language version 1.6 book - Part 41 of 189
The Ring programming language version 1.6 book - Part 41 of 189The Ring programming language version 1.6 book - Part 41 of 189
The Ring programming language version 1.6 book - Part 41 of 189Mahmoud Samir Fayed
 
Break Even Analysis
Break Even AnalysisBreak Even Analysis
Break Even AnalysisARIES TIBAR
 
Introduction to Python - Training for Kids
Introduction to Python - Training for KidsIntroduction to Python - Training for Kids
Introduction to Python - Training for KidsAimee Maree Forsstrom
 
Test Doubles - stubs, spies & mocks
Test Doubles - stubs, spies & mocksTest Doubles - stubs, spies & mocks
Test Doubles - stubs, spies & mocksRubén Bernárdez
 
Clean Architecture Applications in Python
Clean Architecture Applications in PythonClean Architecture Applications in Python
Clean Architecture Applications in PythonSubhash Bhushan
 

Ähnlich wie TDD As If You Meant It (20)

TDD, BDD and mocks
TDD, BDD and mocksTDD, BDD and mocks
TDD, BDD and mocks
 
Por qué usar Spock en lugar de JUnit / Mockito para tus tests Java - Codemoti...
Por qué usar Spock en lugar de JUnit / Mockito para tus tests Java - Codemoti...Por qué usar Spock en lugar de JUnit / Mockito para tus tests Java - Codemoti...
Por qué usar Spock en lugar de JUnit / Mockito para tus tests Java - Codemoti...
 
Decimals part 02
Decimals   part 02 Decimals   part 02
Decimals part 02
 
Domain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with RailsDomain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with Rails
 
Module 7
Module 7Module 7
Module 7
 
Testing in Django
Testing in DjangoTesting in Django
Testing in Django
 
CSC139 Chapter 9 Lab Assignments (1) Classes and Obj.docx
CSC139 Chapter 9 Lab Assignments (1) Classes and Obj.docxCSC139 Chapter 9 Lab Assignments (1) Classes and Obj.docx
CSC139 Chapter 9 Lab Assignments (1) Classes and Obj.docx
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
The Ring programming language version 1.6 book - Part 41 of 189
The Ring programming language version 1.6 book - Part 41 of 189The Ring programming language version 1.6 book - Part 41 of 189
The Ring programming language version 1.6 book - Part 41 of 189
 
Break Even Analysis
Break Even AnalysisBreak Even Analysis
Break Even Analysis
 
Introduction to Python - Training for Kids
Introduction to Python - Training for KidsIntroduction to Python - Training for Kids
Introduction to Python - Training for Kids
 
Flowchart
FlowchartFlowchart
Flowchart
 
fm10e ch 10.pptx
fm10e ch 10.pptxfm10e ch 10.pptx
fm10e ch 10.pptx
 
T4
T4T4
T4
 
Introduction to c part -1
Introduction to c   part -1Introduction to c   part -1
Introduction to c part -1
 
Vb scripting
Vb scriptingVb scripting
Vb scripting
 
Test Doubles - stubs, spies & mocks
Test Doubles - stubs, spies & mocksTest Doubles - stubs, spies & mocks
Test Doubles - stubs, spies & mocks
 
Calculator Processing
Calculator ProcessingCalculator Processing
Calculator Processing
 
Vba class 4
Vba class 4Vba class 4
Vba class 4
 
Clean Architecture Applications in Python
Clean Architecture Applications in PythonClean Architecture Applications in Python
Clean Architecture Applications in Python
 

Mehr von Alexandru Bolboaca (20)

Refactor legacy code through pure functions
Refactor legacy code through pure functionsRefactor legacy code through pure functions
Refactor legacy code through pure functions
 
Design Without Types
Design Without TypesDesign Without Types
Design Without Types
 
Thinking in Functions
Thinking in FunctionsThinking in Functions
Thinking in Functions
 
Raising the Bar
Raising the BarRaising the Bar
Raising the Bar
 
The Journey to Master Code Design
The Journey to Master Code DesignThe Journey to Master Code Design
The Journey to Master Code Design
 
What is good software design? And why it matters?
What is good software design? And why it matters?What is good software design? And why it matters?
What is good software design? And why it matters?
 
Functional programming in C++
Functional programming in C++Functional programming in C++
Functional programming in C++
 
Agile Technical Leadership
Agile Technical LeadershipAgile Technical Leadership
Agile Technical Leadership
 
Usable Software Design
Usable Software DesignUsable Software Design
Usable Software Design
 
Hidden loops
Hidden loopsHidden loops
Hidden loops
 
Removing structural duplication
Removing structural duplicationRemoving structural duplication
Removing structural duplication
 
Continuous delivery
Continuous deliveryContinuous delivery
Continuous delivery
 
Why You Should Start Using Docker
Why You Should Start Using DockerWhy You Should Start Using Docker
Why You Should Start Using Docker
 
Pyramid of-developer-skills
Pyramid of-developer-skillsPyramid of-developer-skills
Pyramid of-developer-skills
 
Applied craftsmanship
Applied craftsmanshipApplied craftsmanship
Applied craftsmanship
 
Pyramid of-developer-skills
Pyramid of-developer-skillsPyramid of-developer-skills
Pyramid of-developer-skills
 
Stay focused
Stay focusedStay focused
Stay focused
 
Kanban intro
Kanban introKanban intro
Kanban intro
 
Unit testing-patterns
Unit testing-patternsUnit testing-patterns
Unit testing-patterns
 
Incremental design, simply explained
Incremental design, simply explainedIncremental design, simply explained
Incremental design, simply explained
 

Kürzlich hochgeladen

TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 

Kürzlich hochgeladen (20)

TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 

TDD As If You Meant It

  • 1. TDD As If You Meant It Alex Bolboacă,  @alexboly,  alex.bolboaca@mozaicworks.com October 2017
  • 2. Test Driven Development TDD As If You Meant It A Simple Example Practising TDD As If You Meant It Applying TDD As If You Meant It in Production Closing
  • 4. Like Brewing Coffee TDD is like brewing coffee
  • 5. My Definition A process for designing software incrementally by clarifying the problem before the solution, and allowing the solution to appear from the tension between tests and existing code.
  • 6. Emergent design The design is an emergent property because it appears from a combination of properties of programmer, test code and production code.
  • 7. So, … When doing “pure” TDD, you shouldn’t start with any preconceived ideas about the solution
  • 8. But… Most of the time we fail at this rule
  • 9. Goal The goal is not to ignore your past experience. The goal is to allow yourself to gather more experiences.
  • 10. TDD As If You Meant It
  • 11. What Is It? A set of constraints that force the practise of “pure” TDD.
  • 12. Constraints You are not allowed to create any: • named constant • variable • method • class other than by refactoring it out of a test.
  • 13. Constraints All production code is first written in tests and then extracted through refactoring
  • 15. We Need A Problem Bank account kata Think of your personal bank account experience. When in doubt, go for the simplest solution. Requirements • Deposit and Withdrawal • Transfer • Account statement (date, amount, balance) • Statement printing • Statement filters (just deposits, withdrawal, date) Source: https://github.com/sandromancuso/Bank-kata/
  • 17. First test def ”the first test”(){ expect: false }
  • 18. Isn’t this beautiful? Let’s take the time to properly admire the serenity and simplicity of this test ⌣
  • 20. False in programming In logic, false is a truth value associated to an assertion. In programming false is either a constant or the result of a boolean operation.
  • 21. So what is false? def ”after a deposit of €5 in an empty account its balance is €5”{ expect: 424532534 == 5 }
  • 22. Make the first test pass def ”after a deposit of €5 in an empty account its balance is €5”{ expect: 0 + 5 == 5 }
  • 24. Refactor Remember We’re only allowed to: • extract constant • extract variable • remove duplication
  • 25. The test needs more clarity 0 + 5 == 5 What is 5? What is 0? • 0: initial account balance • first 5: deposit amount • second 5: final account balance  Accidental duplication!
  • 26. Clarity def ”after a deposit of €5 in an empty account its balance is €5”{ given: def expectedFinalBalance = 5 def initialBalance = 0 def amount = 5 when: def finalBalance = initialBalance + amount then: finalBalance == expectedFinalBalance }
  • 27. Notions … Let’s take a look at the notions we’re using: • deposit amount • empty account • balance • initial balance • final balance
  • 28. Semantics Empty account = account that has an initial balance of 0  Duplication!
  • 29. Express it! def ”after depositing €5 in an account with balance 0 its balance is €5”{ given: def expectedFinalBalance = 5 def initialBalance = 0 def amount = 5 when: // Production code def finalBalance = initialBalance + amount then: finalBalance == expectedFinalBalance }
  • 30. Next test? Triangulation: the process of writing another test that changes a single input from the input set with the goal of advancing towards the solution
  • 31. Triangulation - Advanced We triangulate in the topology of possible solutions
  • 32. What can we triangulate on? • initial balance • deposit amount • currency (€, RON, £) • account (eg. ownership, type of account etc.)
  • 34. What are interesting values for deposit? Value sampling or Equivalence partitioning Since we cannot test all the values, find the intervals that are interesting and pick at least one value from each interval
  • 35. Equivalence partitioning for deposit • Negative numbers: e.g. -€1, -€5 • Zero • Positive numbers • Minimum ? • Maximum ? • Non-integers: e.g. €1.50, €99.99
  • 36. Questions, questions… Can an account have negative balance? Yes Can we deposit a negative amount? No What’s the maximum amount in an account? Use €1.000.000.000 What’s the minimum amount in an account? Use -€10.000 What’s the minimum deposit? Use €1 What’s the maximum deposit? Use €1.000.000.000
  • 37. So, triangulation on deposit Accepted values: • Minimum: €1 • Any value between €1 and €1.000.000.000 • Maximum: €1.000.000.000 (in an account with 0) Invalid values: • Less than minimum: €0.99 • More than maximum: €1.000.000.000,01
  • 38. Second test def ”after a deposit of €1 in an account with balance 0 its balance is €1”{ expect: false }
  • 39. What is false? def ”after a deposit of €1 in an account with balance 0 its balance is €1”{ expect: 1 == 0 + 241234123423 }
  • 40. Make it pass def ”after a deposit of €1 in an account with balance 0 its balance is €1”{ expect: 1 == 0 + 1 }
  • 41. Refactor to clarify def ”after a deposit of €1 in an account with balance 0 its balance is €1”{ given: def initialBalance = 0 def amount = 1 def expectedFinalBalance = 1 when: //Production code def finalBalance = initialBalance + amount then: expectedFinalBalance == finalBalance }
  • 43. Rule of three Rule of Three  Remove duplication after you’ve seen it for 3 or more times
  • 44. So, next test def ”after a deposit of €1.000.000.000 in an account with balance 0 its balance is €1.000.000.000”{ expect: false }
  • 45. 5 minutes later … def ”after a deposit of €1.000.000.000 in an account with balance 0 its balance is €1.000.000.000”{ given: def initialBalance = 0 def amount = 1000000000 def expectedFinalBalance = 1000000000 when: //Production code def finalBalance = initialBalance + amount then: expectedFinalBalance == finalBalance }
  • 46. Anything else to refactor? Q: What is 1.000.000.000? A: Maximum balance for an account in € is €1.000.000.000.
  • 47. Extract max balance static final maxBalance = 1000000000 def ”after a deposit of #maxBalance in an account with balance 0 its balance is #maxBalance”{ given: def initialBalance = 0 def amount = maxBalance def expectedFinalBalance = maxBalance when: //Production code def finalBalance = initialBalance + amount then: expectedFinalBalance == finalBalance }
  • 48. How to Remove Duplication? Two options: • remove duplication from tests using data driven tests • remove duplication from production code using a method
  • 49. Data driven tests? def ”after a deposit of #amount in an account with balance #balance its balance is #expectedFinalBalance”{ when: ”deposit” def finalBalance = initialBalance + amount then: expectedFinalBalance == finalBalance where: initialBalance | amount || expectedFinalBalance 0 | 1 || 1 0 | 5 || 5 0 | maxBalance || maxBalance
  • 50. Hmm…  Feels like it doesn’t advance the solution Spoiler: I’ll come back to this later
  • 51. Extract production code def deposit(initialBalance, amount){ return initialBalance + amount }
  • 53. Let’s reflect • We didn’t write a lot of code: three tests and one line of production code • We learned a lot about the domain • We learned a lot about the business rules • We named things • We have the simplest solution to the problem so far • It feels slow
  • 54. Most importantly We can see how the code evolves: constant -> variable -> method
  • 55. Let’s Look Into The Future: Deposit static final maxBalance = 1000000000 def deposit(amount, initialBalance){ if(amount < 1) return initialBalance if(initialBalance + amount > maxBalance) return initialBalance return initialBalance + amount }
  • 56. Let’s Look Into The Future: Withdrawal static final minBalance = -50000 def withdraw(amount, initialBalance){ if(amount < 1) return initialBalance if(initialBalance - amount < minBalance) return initialBalance return initialBalance - amount }
  • 57. We have a design choice Go functional or go Object Oriented
  • 58. Functional solution def balance = deposit(10, withdraw(200, withdraw(500, withdraw(10, deposit(1000, /*initialBalance*/ 0)))))
  • 59. Object Oriented Solution def account = new Account(balance: 0) account.deposit(1000) account.withdraw(10) account.withdraw(500) account.withdraw(200) account.deposit(10) def balance = account.balance
  • 60. Different Object Oriented Solution def account = new Account(balance: 0) def transactions = [ new DepositTransaction(amount: 1000), new WithdrawalTransaction(amount: 10), new WithdrawalTransaction(amount: 500), new WithdrawalTransaction(amount: 200), new DepositTransaction(amount: 10) ] account.applyTransactions(transactions) def balance = account.balance
  • 61. What’s the difference? A class is nothing more than a set of cohesive, partially applied pure functions – via JB Rainsberger
  • 62. Partially applied function account.deposit(amount) is a partial application of: deposit(amount, initialBalance)
  • 63. And now for something completely different… Pssst… Huge Monty Python fan here
  • 64. Let’s rewind … def ”after a deposit of #deposit in an account with balance 0 its balance is #deposit”{ when: ”deposit” def finalBalance = initialBalance + amount then: expectedFinalBalance == finalBalance where: initialBalance | amount || expectedFinalBalance 0 | 1 || 1 0 | 5 || 5 0 | maxBalance || maxBalance
  • 65. And reinterpret this Whenever we deposit a deposit amount less or equal to the maximum balance into an account that has initial balance 0, the resulting balance is the deposit amount  Property based testing
  • 66. Spock Genesis spock-genesis library https://github.com/Bijnagte/spock-genesis A library that helps generating values for properties
  • 67. A property based test def ”after a deposit in an account with balance 0 its balance is the deposit amount”{ when: ”deposit” def finalBalance = deposit(amount, initialBalance) then: expectedFinalBalance == finalBalance where: amount << integer(1..maxBalance).take(500) initialBalance = 0 expectedFinalBalance = amount
  • 68. Reflection time • We’ve learned more about software design • We’ve learned more about testing • We left our options open until we picked functional or OO approach • We decided step by step what’s the right next step • Still feels slow
  • 69. Practising TDD As If You Meant It
  • 70. How • Pick any kata, or a pet project • Set up a timer at 45’ • Do it every day for 10 days (continue where you left off) • Reflect on the way the design evolves, and on the design options you took •  Make every decision as deliberate as possible
  • 71. Applying TDD As If You Meant It in Production
  • 72. Do It Like Mythbusters Mythbusters
  • 73. How? • Separate a small(ish) problem. Eg: special alerts in a web application, validation in client-side code, a UI control etc.
  • 74. How? • Separate a small(ish) problem. Eg: special alerts in a web application, validation in client-side code, a UI control etc. • Start a new test suite (maybe even a new project)
  • 75. How? • Separate a small(ish) problem. Eg: special alerts in a web application, validation in client-side code, a UI control etc. • Start a new test suite (maybe even a new project) • Write the implementation using TDD as If You Meant It
  • 76. How? • Separate a small(ish) problem. Eg: special alerts in a web application, validation in client-side code, a UI control etc. • Start a new test suite (maybe even a new project) • Write the implementation using TDD as If You Meant It • When you have the production code, integrate it with the rest of the code
  • 78. Conclusions TDD As If You Meant It has helped me become more deliberate about software design. • Despite feeling slow, I found it is quite fast after practising
  • 79. Conclusions TDD As If You Meant It has helped me become more deliberate about software design. • Despite feeling slow, I found it is quite fast after practising • It helped me understand more about functional programming
  • 80. Conclusions TDD As If You Meant It has helped me become more deliberate about software design. • Despite feeling slow, I found it is quite fast after practising • It helped me understand more about functional programming • The feeling of working on a small, clean, piece of code instead of the “big” code is very liberating
  • 81. My advice Embrace constraints “I have never been forced to accept compromises but I have willingly accepted constraints” Charles Eames, Designer and Architect
  • 82. Learn more Adi’s Blog http://blog.adrianbolboaca.ro
  • 83. Thank you! I’ve been Alex Bolboacă, @alexboly, alex.bolboaca@mozaicworks.com programmer, trainer, mentor, writer at Mozaic Works Think. Design. Work Smart. https://mozaicworks.com