2010-07-19_rails_tdd_week1

33
Efficient Rails Test-Driven Efficient Rails Test-Driven Development Development Wolfram Arnold Wolfram Arnold www.rubyfocus.biz www.rubyfocus.biz In collaboration with: In collaboration with: Sarah Allen, BlazingCloud.net Sarah Allen, BlazingCloud.net marakana.com marakana.com

description

Efficient Rails Test-Driven Development Week #1. A class by Wolfram Arnold of rubyfocus.biz, in collaboration with Sarah Allen of blazingcloud.net and marakana.com

Transcript of 2010-07-19_rails_tdd_week1

Page 1: 2010-07-19_rails_tdd_week1

Efficient Rails Test-Driven Efficient Rails Test-Driven DevelopmentDevelopment

Wolfram ArnoldWolfram Arnoldwww.rubyfocus.bizwww.rubyfocus.biz

In collaboration with:In collaboration with:Sarah Allen, BlazingCloud.netSarah Allen, BlazingCloud.net

marakana.commarakana.com

Page 2: 2010-07-19_rails_tdd_week1

Class OutlineClass Outline

Week #1

The economics of testing

Testing in layers, design patterns

Toolbox: RSpec with Rails

RSpec & Models

Week #2

A culture of testing: Why TDD? How to TDD?

Testing & Data Dependencies

Toolbox: Fixtures, Factories, Mocks & Stubs

Page 3: 2010-07-19_rails_tdd_week1

Class OutlineClass Outline

Week #3

Controller testing

View, Helper, Routes Testing

How much is enough? How much is too much?

Week #4

Refactoring code & tests, custom matchers

API Testing

Remote data setup

Cucumber for API testing & documentation

Page 4: 2010-07-19_rails_tdd_week1

Class OutlineClass Outline

Week #5

Integration Testing—when and how?

Toolbox: Cucumber, Selenium & Friends

Page Object Pattern

Week #6

TDD—what next?

BDD, Agile Process, XP → VDD: Value-Driven Development

Advanced/Special Requests

Page 5: 2010-07-19_rails_tdd_week1

What you can expectWhat you can expect

Presentation, Examples

Answers to questions

A range of material from current development practice

Homework

Fluidity & adaptability

Fun

Page 6: 2010-07-19_rails_tdd_week1

It works best, when...It works best, when...

Active participation

Try something new

Focus

Team Effort

Pairing

Utilizing the resources in class: TA's, participants

Discussions in public

Class Q&A

Mailing list

Page 7: 2010-07-19_rails_tdd_week1

Efficient Rails Test-Driven Development

Page 8: 2010-07-19_rails_tdd_week1

Why “efficient” and “testing”?Why “efficient” and “testing”?

“Testing takes too much time.”

“It's more efficient to test later.”

“Testing is the responsibility of QA, not developers.”

“It's not practical to test X.”

Tests break when data changes.

Tests break when design changes.

Page 9: 2010-07-19_rails_tdd_week1

The Role of TestingThe Role of Testing

Development without tests...

fails to empower developers to efficiently take responsibility for quality of the code delivered

makes collaboration harder

build narrow silos of expertise

instills fear & resistance to change

makes documentation a chore

stops being efficient very soon

Page 10: 2010-07-19_rails_tdd_week1

TDD: Keeping cost of change lowTDD: Keeping cost of change low

Cost per change

Time

withTDD

withoutTDD

Page 11: 2010-07-19_rails_tdd_week1

Why?Why?

Non-TDD

Accumulates “technical debt” unchecked

Removal of technical debt carries riskThe more technical debt, the higher the risk

Existing technical debt attracts more technical debtLike compound interest

People are most likely to do what others did before them

To break the pattern heroic discipline & coordination required

Page 12: 2010-07-19_rails_tdd_week1

Testing in LayersTesting in Layers

ModelRSpecModel

ControllerRSpec

Controller

ViewsRSpecHelpers

HelpersRSpecViews

Routes

Test::Unit

Test::Unit FunctionalRSpecRoutes

Application, Server

Application, Browser UI

RSpec IntegrationCucumber, Webrat

Selenium

Test::Unit Integration

Page 13: 2010-07-19_rails_tdd_week1

Cost of TestingCost of Testing

Model

Controller

Views Helpers

Routes

Application, Server

Application, Browser UI

Cost

Layers

Page 14: 2010-07-19_rails_tdd_week1

Cost of TestingCost of Testing

Model

Controller

Views Helpers

Routes

Application, Server

Application, Browser UI

Relationship to data

Cost

mostremoved

closest

Page 15: 2010-07-19_rails_tdd_week1

Best ROI for TestingBest ROI for Testing

Model

Controller

Views Helpers

Routes

Application, Server

Application, Browser UI

Layers

Impact/Line of Test Code

Page 16: 2010-07-19_rails_tdd_week1

TDD & Design PatternsTDD & Design Patterns

Skinny Controller—Fat Model

DRY

named_scope

Proxy Associations

Validations

...

➢ Designed to move logic from higher to lower application layers

➢ Following design patterns makes testing easier

➢ Code written following TDD economics will naturally converge on these design patterns!

Page 17: 2010-07-19_rails_tdd_week1

Structure of TestsStructure of Tests

Setup

Expected value

Actual value

Verification: actual == expected?

Teardown

Page 18: 2010-07-19_rails_tdd_week1

Good Tests are...Good Tests are...

Compact

Responsible for testing one concern only

Fast

DRY

Page 19: 2010-07-19_rails_tdd_week1

RSpec VerificationsRSpec Verifications

should respond_to

should be_nil

→ works with any ? method (so-called “predicates”)

should be_valid

should_not be_nil; should_not be_valid

lambda {...}.should change(), {}, .from().to(), .by()

should eql, ==, equal

Page 20: 2010-07-19_rails_tdd_week1

RSpec StructureRSpec Structure

before, before(:each), before(:all)

after, after(:each), after(:all)

describe do...end, nested

it do... end

Page 21: 2010-07-19_rails_tdd_week1

Let's do some codingLet's do some coding

Demo

Page 22: 2010-07-19_rails_tdd_week1

Models: What to test?Models: What to test?

Validation Rules

Associations

Any custom method

Association Proxy Methods

Page 23: 2010-07-19_rails_tdd_week1

Let's do some codingLet's do some coding

Exercise, but wait...

Page 24: 2010-07-19_rails_tdd_week1

Test-First TeachingTest-First Teaching

Pioneered by Sarah Allen

Instructor writes tests

Students write code

What about writing tests?

Page 25: 2010-07-19_rails_tdd_week1

Behavior-First TeachingBehavior-First Teaching

Instructor specifies desired behavior

in plain English

like a user story

Students write tests

Students write code to make tests pass

Page 26: 2010-07-19_rails_tdd_week1

Story Exercise #1Story Exercise #1

A Person object must have a first and last name.

A Person object can construct a full name from the first and last name.

A Person object has an optional middle name.

A Person object returns a full name including, if present, the middle name.

Page 27: 2010-07-19_rails_tdd_week1

RSpec ==, eql, equalRSpec ==, eql, equal

obj.should == 5

obj.should eql(5)

obj.should equal(5)

5 == 5

5.eql 5

5.equal 5

Object Equality vs. Identity

eql, == compare values

equal, === compare objects,classes

Warning! Do not use != with RSpec.Use should_not instead.

Use ==Unless you know you need something else

Page 28: 2010-07-19_rails_tdd_week1

RSpec should changeRSpec should change

lambda {Person.create

}.should change(Person, :count).by(1)

lambda {@bob.addresses.create(:street => “...”)

}.should change(@bob.addresses, :count).by(1)

Warning: The 2nd example is incorrect!

Page 29: 2010-07-19_rails_tdd_week1

RSpec should changeRSpec should change

lambda {# code that causes a change

}.should change(object, :method).by(difference)

or

should change(object, :method).from(initial).to(final)

The object typically is a class, if not, be wary of reload!

Page 30: 2010-07-19_rails_tdd_week1

should change with blockshould change with block

lambda {# code that causes a change

}.should change { expression }.by(difference)

or

should change { expression }.from(initial).to(final)

Page 31: 2010-07-19_rails_tdd_week1

better with blockbetter with block

lambda {@bob.addresses.create(:street => “...”)

}.should change {@bob.addresses(true).count }.by(1)

Page 32: 2010-07-19_rails_tdd_week1

HomeworkHomework

A Person should save correctly.

A Person can have many Addresses.

A Person's Address must have a street, city and zip.

A Person's Address can have an optional country.

If the country is left blank, it should default to “USA” prior to saving.

Page 33: 2010-07-19_rails_tdd_week1

BizConfBizConf

Aug 4-6, 2010

Amelia Island, FL

Discount code: WOLF

for 43% off

http://bizconf.org?coupon=WOLF

Rails & Web App Professionals, Entrepreneurs, Consultants

Small group

Network with Who's Who

Organized by Obie Fernandez of Hashrocket

Highlight: David Allen