Test Driven Development: A Love Story

Preview:

Citation preview

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 GriefDenialAnger

BargainingDepressionAcceptance

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 testedcode 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 StepsVisit form

Tuesday, April 16, 13

User Steps Test StepsVisit form

Leave field blank

Tuesday, April 16, 13

User Steps Test StepsVisit form

Leave field blank

Click “Submit”

Tuesday, April 16, 13

User Steps Test StepsVisit form

Leave field blank

Click “Submit”

Application crashes

Tuesday, April 16, 13

User Steps Test StepsVisit form

Leave field blank

Click “Submit”

Application crashes

New object

Tuesday, April 16, 13

User Steps Test StepsVisit form

Leave field blank

Click “Submit”

Application crashes

New object

Leave field blank

Tuesday, April 16, 13

User Steps Test StepsVisit form

Leave field blank

Click “Submit”

Application crashes

New object

Leave field blank

Save object

Tuesday, April 16, 13

User Steps Test StepsVisit 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.newnew_object.required = nil

Tuesday, April 16, 13

it “returns a useful error” do

end

new_object = Object.newnew_object.required = nilnew_object.save!

Tuesday, April 16, 13

it “returns a useful error” do

end

new_object = Object.newnew_object.required = nilnew_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

WriteTest

Tuesday, April 16, 13

Write Code

Manually Test

Modify Code

Manually Test

WriteTest

Modify Code

Tuesday, April 16, 13

Write Code

Manually Test

Modify Code

Manually Test

WriteTest

Modify Code

Manually Test

Tuesday, April 16, 13

Write Code

Manually Test

Modify Code

Manually Test

WriteTest

Modify Code

Manually Test

ModifyTest

Tuesday, April 16, 13

Testing last leaves holes in test coverage

Tuesday, April 16, 13

Write FailingTest

Tuesday, April 16, 13

Write FailingTest

Make Test Pass

Tuesday, April 16, 13

Write FailingTest

Make Test Pass

Refactor

Tuesday, April 16, 13

Write FailingTest

Make Test Pass

Refactor

Red

Tuesday, April 16, 13

Write FailingTest

Make Test Pass

Refactor

Red Green

Tuesday, April 16, 13

Write FailingTest

Make Test Pass

Refactor

Red Green Refactor

Tuesday, April 16, 13

Never write new functionality without

a failing test- Steve Freeman

& Nat PryceTuesday, 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 == .095end

Tuesday, April 16, 13

it “returns the correct rate” do tax_rate(seattle).should == .095endit “creates a new object” do get :new assigns(new_object).should_be new_recordend

Tuesday, April 16, 13

it “returns the correct rate” do tax_rate(seattle).should == .095endit “creates a new object” do get :new assigns(new_object).should_be new_recordendit “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

ModularLoosely CoupledSmall 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 FAILSX

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 withBlue Box Inc

@nellshamrellTuesday, April 16, 13