SlideShare a Scribd company logo
1 of 113
Download to read offline
A Love Story
@nellshamrell
Test Driven Development
Tuesday, April 16, 13
Code
Tuesday, April 16, 13
Legacy Code
Tuesday, April 16, 13
Tuesday, April 16, 13
Tuesday, April 16, 13
Tuesday, April 16, 13
Grief
Tuesday, April 16, 13
Stages of Grief
Denial
Anger
Bargaining
Depression
Acceptance
Tuesday, April 16, 13
Grief
Tuesday, April 16, 13
Test Driven Development
is the key
TDD
Tuesday, April 16, 13
Tuesday, April 16, 13
Denial
Tuesday, April 16, 13
I will write tests
when I have time
Tuesday, April 16, 13
Changed
Class
Tuesday, April 16, 13
Changed
Class
Unrelated
Class
Unrelated
Class
Tuesday, April 16, 13
Changed
Class
Unrelated
Class
Unrelated
Class
Unrelated
Class
Tuesday, April 16, 13
Changed
Class
Unrelated
Class
Unrelated
Class
Unrelated
Class
Unrelated
Class
Unrelated
Class
Unrelated
Class
Unrelated
Class
Unrelated
Class
Unrelated
Class
Unrelated
Class
Tuesday, April 16, 13
Deploying without tests
is flying blind
Tuesday, April 16, 13
A magical, better time in
the future never comes
Tuesday, April 16, 13
The more stress you
feel, the less testing
you will do...
- Kent Beck
Tuesday, April 16, 13
The less testing you
do, the more errors
you will make
- Kent Beck
Tuesday, April 16, 13
The ideal time to
write tests is now
Tuesday, April 16, 13
But...where do I start?
Tuesday, April 16, 13
Tuesday, April 16, 13
Anger
Tuesday, April 16, 13
What were they
thinking?!
Tuesday, April 16, 13
I cannot change
past actions
Tuesday, April 16, 13
I can only change
my own actions
Tuesday, April 16, 13
Adding tests to legacy
code takes time
Tuesday, April 16, 13
Take small steps that
can be verified
- Noel Rappin
Tuesday, April 16, 13
Any new code
must have tests
Tuesday, April 16, 13
New Code
Legacy
Code
Call new tested
code from legacy
code
Tuesday, April 16, 13
Bugs in code must be
reproduced with a test
Tuesday, April 16, 13
User Steps Test Steps
Tuesday, April 16, 13
User Steps Test Steps
Visit form
Tuesday, April 16, 13
User Steps Test Steps
Visit form
Leave field blank
Tuesday, April 16, 13
User Steps Test Steps
Visit form
Leave field blank
Click “Submit”
Tuesday, April 16, 13
User Steps Test Steps
Visit form
Leave field blank
Click “Submit”
Application
crashes
Tuesday, April 16, 13
User Steps Test Steps
Visit form
Leave field blank
Click “Submit”
Application
crashes
New object
Tuesday, April 16, 13
User Steps Test Steps
Visit form
Leave field blank
Click “Submit”
Application
crashes
New object
Leave field blank
Tuesday, April 16, 13
User Steps Test Steps
Visit form
Leave field blank
Click “Submit”
Application
crashes
New object
Leave field blank
Save object
Tuesday, April 16, 13
User Steps Test Steps
Visit form
Leave field blank
Click “Submit”
Application
crashes
New object
Leave field blank
Save object
Test returns
exception
Tuesday, April 16, 13
What should my code do?
Tuesday, April 16, 13
it “returns a useful error” do
end
Tuesday, April 16, 13
it “returns a useful error” do
end
new_object = Object.new
Tuesday, April 16, 13
it “returns a useful error” do
end
new_object = Object.new
new_object.required = nil
Tuesday, April 16, 13
it “returns a useful error” do
end
new_object = Object.new
new_object.required = nil
new_object.save!
Tuesday, April 16, 13
it “returns a useful error” do
end
new_object = Object.new
new_object.required = nil
new_object.save!
new_object.errors.should include
(“Required field is blank”)
Tuesday, April 16, 13
Use tests to learn
legacy code
Tuesday, April 16, 13
Tuesday, April 16, 13
Bargaining
Tuesday, April 16, 13
I write my code,
then write my test
Tuesday, April 16, 13
Write
Code
Write
Tests
Tuesday, April 16, 13
Write
Code
Tuesday, April 16, 13
Write
Code
Manually
Test
Tuesday, April 16, 13
Write
Code
Manually
Test
Modify
Code
Tuesday, April 16, 13
Write
Code
Manually
Test
Modify
Code
Manually
Test
Tuesday, April 16, 13
Write
Code
Manually
Test
Modify
Code
Manually
Test
Write
Test
Tuesday, April 16, 13
Write
Code
Manually
Test
Modify
Code
Manually
Test
Write
Test
Modify
Code
Tuesday, April 16, 13
Write
Code
Manually
Test
Modify
Code
Manually
Test
Write
Test
Modify
Code
Manually
Test
Tuesday, April 16, 13
Write
Code
Manually
Test
Modify
Code
Manually
Test
Write
Test
Modify
Code
Manually
Test
Modify
Test
Tuesday, April 16, 13
Testing last leaves
holes in test coverage
Tuesday, April 16, 13
Write
Failing
Test
Tuesday, April 16, 13
Write
Failing
Test
Make
Test
Pass
Tuesday, April 16, 13
Write
Failing
Test
Make
Test
Pass
Refactor
Tuesday, April 16, 13
Write
Failing
Test
Make
Test
Pass
Refactor
Red
Tuesday, April 16, 13
Write
Failing
Test
Make
Test
Pass
Refactor
Red Green
Tuesday, April 16, 13
Write
Failing
Test
Make
Test
Pass
Refactor
Red Green Refactor
Tuesday, April 16, 13
Never write new
functionality without
a failing test
- Steve Freeman
& Nat Pryce
Tuesday, April 16, 13
Testing is about trust
- Robert C. Martin
Tuesday, April 16, 13
Tuesday, April 16, 13
Depression
Tuesday, April 16, 13
What’s the
point?
Tuesday, April 16, 13
Change will happen
Tuesday, April 16, 13
Every line of tested
code is reliable code
Tuesday, April 16, 13
Every line of untested
code is unreliable code
Tuesday, April 16, 13
Do the right thing
Tuesday, April 16, 13
Tuesday, April 16, 13
Acceptance
Tuesday, April 16, 13
Tests prevent breaking
Tuesday, April 16, 13
Tests are
documentation
Tuesday, April 16, 13
it “returns the correct rate” do
tax_rate(seattle).should == .095
end
Tuesday, April 16, 13
it “returns the correct rate” do
tax_rate(seattle).should == .095
end
it “creates a new object” do
get :new
assigns(new_object).should_be
new_record
end
Tuesday, April 16, 13
it “returns the correct rate” do
tax_rate(seattle).should == .095
end
it “creates a new object” do
get :new
assigns(new_object).should_be
new_record
end
it “saves to the database” do
expect(save_method).to
change{Table.count}.by(1)
end
Tuesday, April 16, 13
Test Driven Code
is better code
Tuesday, April 16, 13
Modular
Loosely Coupled
Small Methods
Test Driven Code is...
Tuesday, April 16, 13
Tests remove fear
Tuesday, April 16, 13
Tuesday, April 16, 13
Love
Tuesday, April 16, 13
Test Drive an
external API?
Tuesday, April 16, 13
My Code API
Tuesday, April 16, 13
My Code API
Calls API method
Tuesday, April 16, 13
My Code API
Calls API method
Sends response
Tuesday, April 16, 13
Mocks and Stubs
Tuesday, April 16, 13
A stub is a stand in
for an object called
by my code
Tuesday, April 16, 13
My Code API Stub
Tuesday, April 16, 13
My Code
Calls API method
API Stub
Tuesday, April 16, 13
My Code
Calls API method
Sends scripted
response
API Stub
Tuesday, April 16, 13
Mocks are
“stubs with attitude”
- Russ Olsen
Tuesday, April 16, 13
My Code API Mock
Tuesday, April 16, 13
My Code
Calls API method
API Mock
Tuesday, April 16, 13
My Code
Calls API method
Sends scripted
response
API Mock
Tuesday, April 16, 13
My Code API Mock
Tuesday, April 16, 13
My Code
Unexpected method call
API Mock
Tuesday, April 16, 13
My Code
Unexpected method call
API Mock
Test FAILS
X
Tuesday, April 16, 13
The truth is out there
(Just need to ask!)
Tuesday, April 16, 13
Testing is
evolving
Tuesday, April 16, 13
Testing is
a journey
Tuesday, April 16, 13
Test Driven Development
changed my code
Tuesday, April 16, 13
Test Driven Development
changed me
Tuesday, April 16, 13
Test Driven Development
is developing
beyond myself
Tuesday, April 16, 13
Code
Tuesday, April 16, 13
Nell Shamrell
Software Development
Engineer with
Blue Box Inc
@nellshamrell
Tuesday, April 16, 13

More Related Content

More from Nell Shamrell-Harrington

Containers, Virtual Machines, and Bare Metal, Oh My!
Containers, Virtual Machines, and Bare Metal, Oh My!Containers, Virtual Machines, and Bare Metal, Oh My!
Containers, Virtual Machines, and Bare Metal, Oh My!Nell Shamrell-Harrington
 
Creating Packages that Run Anywhere with Chef Habitat
Creating Packages that Run Anywhere with Chef HabitatCreating Packages that Run Anywhere with Chef Habitat
Creating Packages that Run Anywhere with Chef HabitatNell Shamrell-Harrington
 
First Do No Harm: Surgical Refactoring (extended edition)
First Do No Harm: Surgical Refactoring (extended edition)First Do No Harm: Surgical Refactoring (extended edition)
First Do No Harm: Surgical Refactoring (extended edition)Nell Shamrell-Harrington
 
A Supermarket of Your Own: Running a Private Chef Supermarket
A Supermarket of Your Own: Running a Private Chef SupermarketA Supermarket of Your Own: Running a Private Chef Supermarket
A Supermarket of Your Own: Running a Private Chef SupermarketNell Shamrell-Harrington
 
Beneath the Surface: Regular Expressions in Ruby
Beneath the Surface: Regular Expressions in RubyBeneath the Surface: Regular Expressions in Ruby
Beneath the Surface: Regular Expressions in RubyNell Shamrell-Harrington
 

More from Nell Shamrell-Harrington (20)

Habitat Service Discovery
Habitat Service DiscoveryHabitat Service Discovery
Habitat Service Discovery
 
Web Operations101
Web Operations101Web Operations101
Web Operations101
 
Rust Traits And You: A Deep Dive
Rust Traits And You: A Deep DiveRust Traits And You: A Deep Dive
Rust Traits And You: A Deep Dive
 
Rust, Redis, and Protobuf - Oh My!
Rust, Redis, and Protobuf - Oh My!Rust, Redis, and Protobuf - Oh My!
Rust, Redis, and Protobuf - Oh My!
 
Containers, Virtual Machines, and Bare Metal, Oh My!
Containers, Virtual Machines, and Bare Metal, Oh My!Containers, Virtual Machines, and Bare Metal, Oh My!
Containers, Virtual Machines, and Bare Metal, Oh My!
 
Chef Vault: A Deep Dive
Chef Vault: A Deep DiveChef Vault: A Deep Dive
Chef Vault: A Deep Dive
 
Open Source Governance 101
Open Source Governance 101Open Source Governance 101
Open Source Governance 101
 
DevOps in Politics
DevOps in PoliticsDevOps in Politics
DevOps in Politics
 
Open Source Governance - The Hard Parts
Open Source Governance - The Hard PartsOpen Source Governance - The Hard Parts
Open Source Governance - The Hard Parts
 
Creating Packages that Run Anywhere with Chef Habitat
Creating Packages that Run Anywhere with Chef HabitatCreating Packages that Run Anywhere with Chef Habitat
Creating Packages that Run Anywhere with Chef Habitat
 
Refactoring terraform
Refactoring terraformRefactoring terraform
Refactoring terraform
 
Refactoring Infrastructure Code
Refactoring Infrastructure CodeRefactoring Infrastructure Code
Refactoring Infrastructure Code
 
Devops: A History
Devops: A HistoryDevops: A History
Devops: A History
 
First Do No Harm: Surgical Refactoring (extended edition)
First Do No Harm: Surgical Refactoring (extended edition)First Do No Harm: Surgical Refactoring (extended edition)
First Do No Harm: Surgical Refactoring (extended edition)
 
First Do No Harm: Surgical Refactoring
First Do No Harm: Surgical RefactoringFirst Do No Harm: Surgical Refactoring
First Do No Harm: Surgical Refactoring
 
A Supermarket of Your Own: Running a Private Chef Supermarket
A Supermarket of Your Own: Running a Private Chef SupermarketA Supermarket of Your Own: Running a Private Chef Supermarket
A Supermarket of Your Own: Running a Private Chef Supermarket
 
Public Supermarket: The Insider's Tour
Public Supermarket: The Insider's TourPublic Supermarket: The Insider's Tour
Public Supermarket: The Insider's Tour
 
Beneath the Surface - Rubyconf 2013
Beneath the Surface - Rubyconf 2013Beneath the Surface - Rubyconf 2013
Beneath the Surface - Rubyconf 2013
 
Beneath the Surface: Regular Expressions in Ruby
Beneath the Surface: Regular Expressions in RubyBeneath the Surface: Regular Expressions in Ruby
Beneath the Surface: Regular Expressions in Ruby
 
Basic Regular Expressions
Basic Regular ExpressionsBasic Regular Expressions
Basic Regular Expressions
 

Test Driven Development: A Love Story