avatars of tdd

47
Licensed Under Creative Commons by Naresh Jain Avatars of TDD Rule of Diversity Distrust all claims for “One True Way” 1 Friday, September 18, 2009

Upload: naresh-jain

Post on 06-May-2015

10.334 views

Category:

Technology


4 download

DESCRIPTION

Presentation on Avatars of TDD and some concepts you need to know before you take a jump to TDD.

TRANSCRIPT

Page 1: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Avatars of TDDRule of Diversity

Distrust all claims for “One True Way”

1Friday, September 18, 2009

Page 2: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Overview

2Friday, September 18, 2009

Page 3: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Overview

2Friday, September 18, 2009

Page 4: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Overview

2Friday, September 18, 2009

Page 5: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the TestPass

Overview

2Friday, September 18, 2009

Page 6: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Fail

Pass

Overview

2Friday, September 18, 2009

Page 7: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Make a little change

Fail

Pass

Overview

2Friday, September 18, 2009

Page 8: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Make a little change

Run the Test

Fail

Pass

Overview

2Friday, September 18, 2009

Page 9: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Make a little change

Run the Test

Fail

Fail

Pass

Overview

2Friday, September 18, 2009

Page 10: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Make a little change

Run the Test

Fail

Pass

Fail

Pass

Overview

2Friday, September 18, 2009

Page 11: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Make a little change

Run the Test

Refactor

Fail

Pass

Fail

Pass

Overview

2Friday, September 18, 2009

Page 12: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Make a little change

Run the Test

Refactor

Fail

Pass

Fail

Pass

Overview

2Friday, September 18, 2009

Page 13: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Make a little change

Run the Test

Refactor

Fail

Pass

Fail

Pass

Overview

2Friday, September 18, 2009

Page 14: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Make a little change

Run the Test

Refactor

Fail

Pass

Fail

Pass

Overview

2Friday, September 18, 2009

Page 15: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Simpleeasy to understand, deal with, use, etc.: a simple matter; simple tools.

not elaborate or artificial; plain: a simple style.

not ornate or luxurious; unadorned: a simple gown.

unaffected; unassuming; modest: a simple manner.

not complicated: a simple design.

not complex or compound; single.

occurring or considered alone; mere; bare: the simple truth; a simple fact.

free of deceit or guile; sincere; unconditional: a frank, simple answer.

common or ordinary: a simple soldier.

not grand or sophisticated; unpretentious: a simple way of life.

humble or lowly: simple folk.

inconsequential or rudimentary.

3Friday, September 18, 2009

Page 16: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

What is Simple Design?

A design that allows you to keep moving forward with least amount of resistance

4Friday, September 18, 2009

Page 20: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Simple Design?

easy to understand, deal with: communicates its intent.

not elaborate or artificial; plain: crisp and concise

not ornate or luxurious; unadorned: minimalistic; least possible components (classes and methods).

unaffected; unassuming; modest: does not have unanticipated side-effects.

not complicated: avoids unnecessary conditional logic.

not complex or compound; single: just does one thing and does it well.

occurring or considered alone; mere; bare: to the point.

6Friday, September 18, 2009

Page 21: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Simple Design? ...

free of deceit or guile; sincere; unconditional: abstracts implementation from intent, but does not deceive someone by concealing or misrepresenting the actual concept.

common or ordinary: built on standard patterns which are well understood.

not grand or sophisticated; unpretentious: fulfills today’s needs without unnecessary bells and whistles (over-engineering).

humble or lowly.

inconsequential or rudimentary: does not draw your attention to unnecessary details; achieves good abstractions

7Friday, September 18, 2009

Page 22: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Summary

Do the Simplest thing that could possibly work

YAGNI

Design Patterns.

Code Smells (Code Screams)

Unix Programming Philosophy

OO Design principles - SOLID, DRY, TDA

Functional Programming - Immutability and Side effect free

Simple Design and TDD go hand in hand

8Friday, September 18, 2009

Page 23: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Why bother about TDD?Confident & Feedback

Design & Code minimalistic and clean

Decoupling and Testable

Safety net of executable, living, up-to-date specification

Learning by listening to your code

Slow down and think

Communicate my design choices

Efficient: Debugging and Manual Testing

Maintain focus

Reduce Wastage: Hand-overs

9Friday, September 18, 2009

Page 24: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Before you take the plunge...

10Friday, September 18, 2009

Page 25: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Before you take the plunge...

System Metaphor

Election Metaphor

‘Google Search Engine’ Metaphor

10Friday, September 18, 2009

Page 26: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Before you take the plunge...

System Metaphor

Election Metaphor

‘Google Search Engine’ Metaphor

Thin Slice

ProTest - Dependency Voter

Profile Picture

10Friday, September 18, 2009

Page 27: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Before you take the plunge...

System Metaphor

Election Metaphor

‘Google Search Engine’ Metaphor

Thin Slice

ProTest - Dependency Voter

Profile Picture

Interaction Design

10Friday, September 18, 2009

Page 28: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Before you take the plunge...

System Metaphor

Election Metaphor

‘Google Search Engine’ Metaphor

Thin Slice

ProTest - Dependency Voter

Profile Picture

Interaction Design

Tracer Bullets: Prototyping, a forgotten Design Practice

10Friday, September 18, 2009

Page 29: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Before you take the plunge...

Micro-Design v/s Macro-Design v/s BUFD

Unit Tests Validates Micro-Design

There is No Spoon

Fluent Interfaces in Test

Behavior (verbs) as Test Class Names

11Friday, September 18, 2009

Page 30: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

There is no SpoonVeterinarian Information System (system responsible for billing & patient history)

ChargeAccountForServices with the following test methods:

makePaymentsAgainstAnAccount()

completePaymentsResultInZeroAmountDueOnReceipt()

incompletePaymentsDisplaysDueAmountOnTheReceipt()

Another test class: GenerateBillsForClientAccount with

notifyIfAccountIsNotDueForPayment()

billContainsTotalCostOfAllServicesTaken()

And another test class: ManageClientVisits with

trackAllServicesTakenByThePatient()

skipVisitIfPatientDidNotTakeAnyService()

12Friday, September 18, 2009

Page 31: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Other Test Naming ConventionOther’s Naming Convention My Naming Convention

itShouldSetAccountToLoggedInWhenPasswordMatches matchingPasswordLogsYouIn

itShouldSetAccountToRevokedAfterThreeFailedLoginAttempts threeFailedLoginAttemptsRevokesYourAccount

itShouldNotSetAccountLoggedInIfPasswordDoesNotMatch nonMatchingPasswordDoesNotLogYouIn

itShouldNotRevokeSecondAccountAfterTwoFailedAttemptsFirstAccount

failedLoginAttemptsOnOtherAccountsDoesNotImpactMyAccount

itShouldNowAllowConcurrentLogins sameUserCannotLoginConcurrently

itShouldThrowExceptionIfAccountNotFound onlyUserWithExistingAccountCanLogin

ItShouldNotBePossibleToLogIntoRevokedAccount userWithRevokedAccountCannotLogin

itShouldResetBackToInitialStateAfterSuccessfulLogin successfulLoginResetsFailedAttemptCount

13Friday, September 18, 2009

Page 33: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Fluent Interfaces@Testpublic void redirectDomainsWithSubDomainsPermanently() { server.redirect(“google.com”).withSubDomain().to(“directi.com”); client_requests(“blog.google.com”);

response = domainForwardingServer.process(request);

assertStatusIs(PermanentRedirect); assertLocationIs(“directi.com/blog”); assertStandardResponseHeaderIsPresent();}

14Friday, September 18, 2009

Page 34: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Fluent Interfaces@Testpublic void redirectDomainsWithSubDomainsPermanently() { server.redirect(“google.com”).withSubDomain().to(“directi.com”); client_requests(“blog.google.com”);

response = domainForwardingServer.process(request);

assertStatusIs(PermanentRedirect); assertLocationIs(“directi.com/blog”); assertStandardResponseHeaderIsPresent();}

User naresh_from_mumbai = new User("naresh", "jains", "mumbai", "india", "indian");Context lets = new Context(userService, dns);IdentitySuggester suggester = new IdentitySuggester(userService, dns, randomNumberGenerator);

@Testpublic void avoidCelebrityNamesInGeneratedIds() { lets.assume("naresh", "jain").isACelebrityName(); List<String> generatedIds = suggester.generateIdsFor(naresh_from_mumbai); lets.assertThat(generatedIds).are("[email protected]", "[email protected]");}

14Friday, September 18, 2009

Page 35: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Avatars of TDD

Business Facing

Technology/Implementation Facing

Dri

ves

Dev

elop

men

t Critique product

Outside In

Inside Out

Brian Marick’s Test Categorization

15Friday, September 18, 2009

Page 36: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Outside In: ATDDFitnesse Document:Assertions: 17 right, 0 wrong, 0 ignored, 0 exceptions

com.vis.billing.fixtures.PaidCashBill

account details

account number patient name owner name

1001 Fluffy Dave Atkins

procedure detailsname costRoutine Office Visit 250

Rabies Vaccination 50

billaccount number? owner name? patient name? total? paid?1001 Dave Atkins Fluffy 300 false

procedure details on the billname costRoutine Office Visit 250

Rabies Vaccination 50

pay Cash

patient name? owner name? account number? bill no? payment method? amount paid?

Fluffy Dave Atkins 1001 1 Cash 300

check paid true

check total 0

16Friday, September 18, 2009

Page 38: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

ATDD: Another ExampleAcceptance test:class FluffyTest < Test::Unit::TestCase def test_examination_and_shots vet = Veterinarian.new clinic = Clinic.new "Main Line health" dave = Owner.new "Dave" fluffy = Patient.new "Fluffy" dave.has fluffy visit = clinic.visit(fluffy, vet) do |v| v.procedure "Rabies vaccination", 50 end invoice = visit.invoice assert_equal invoice.to_s, <<-INVOICE Routine visit: $200 Rabies vaccination: $50 Total: $250 INVOICE receipt = clinic.pay_for visit, 100 assert_equal receipt.to_s, <<-RECEIPT Paid $100 for Routine visit Paid $0 for Rabies vaccination Outstanding: $150 RECEIPT endend

18Friday, September 18, 2009

Page 40: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Inside Out: Unit TDDpublic class ClinicTest { private Clinic clinic = new Clinic();

@Test public void amountOnTheReceiptShouldMatchBillableAmount() throws Exception { Billable billable = new Billable() { public int totalAmount() { return 0; } }; Account dave = new Account(101, "Dave");

Receipt rcpt = clinic.payCash(dave, billable); assertEquals("Amount on receipt does match procedure cost", billable.totalAmount(), rcpt.getAmount()); }

@Test public void customerPayesBillableAmountForCashTransaction() throws Exception { final int billableAmount = 56; class AmountCharged { int charged; }; final AmountCharged charged = new AmountCharged();

Billable billable = new Billable() { public int totalAmount() { return billableAmount; } };

Account dave = new Account(101, "Dave") { public void charge(int amount) { charged.charged = amount; } };

clinic.payCash(dave, billable); assertEquals("Account is not charged billable amount", billableAmount,charged.charged); }}

public class BillableTest {

private static final Account daveSAccount = new Account(101, "Dave"); private static final List<Service> services = new ArrayList<Service>();

@Test public void totalBillableAmountShouldBeZeroIfNoServicesAreProvided() { Billable bill = new Bill(daveSAccount, services); assertEquals("Total amount is not Zero", 0, bill.totalAmount()); }

@Test public void totalBillableAmountShouldBeTotalOfEachServiceProvided() { services.add(new Procedure("Rabies Vaccination", 250)); services.add(new Procedure("Regular office Visit", 50));

Billable bill = new Bill(daveSAccount, services);

assertEquals("Total Amount is not 300", 300, bill.totalAmount()); }

@After public void cleanUp() { services.clear(); }}

20Friday, September 18, 2009

Page 42: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Inside Out: Another Example

public class ChargeAccountForServices { private static final Billable bill = createMock(Billable.class); private static final Accountable account = createMock(Accountable.class); private static final Clinic clinic = new Clinic();

@Before public void setUp() { reset(account); reset(bill); }

@Test public void shouldMakePaymentsAgainstAnAccount() throws Exception { account.paid(bill); replay(account); clinic.pay(300, bill, account); verify(account); }

@Test public void shouldHaveZeroAmountDueOnReceiptIfCompletePaymentIsMade() { expect(bill.amount()).andReturn(300); replay(bill); Receipt receipt = clinic.pay(300, bill, account); verify(bill); assertEquals(300, receipt.amount()); assertEquals(0, receipt.amountDue()); }

@Test public void shouldDisplayAmountDueOnTheReceiptIfIncompletePaymentIsMade() { expect(bill.amount()).andReturn(500); replay(bill); Receipt receipt = clinic.pay(300, bill, account); verify(bill); assertEquals(300, receipt.amount()); assertEquals(200, receipt.amountDue()); }}

22Friday, September 18, 2009

Page 43: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

public class CreateBillForClientAccount { private static final List<Service> services = new ArrayList<Service>(); private static final Accountable account = createMock(Accountable.class); private Bill bill;

@Before public void setUp() { reset(account); }

@Test public void shouldThrowExceptionIfAccountIsNotDueForPayment() { expect(account.isPaymentDue()).andReturn(false); replay(account); try { new Bill(account, null); } catch (NoPaymentDueException e) { // expected } verify(account); }

@After public void cleanUp() { services.clear(); }

@Test public void shouldCreateABillWithTheTotalCostOfAllTheServices() { IMocksControl control = createControl(); Service rabiesVaccination = control.createMock(Service.class); Service routineVisit = control.createMock(Service.class); services.add(rabiesVaccination); services.add(routineVisit);

expect(account.isPaymentDue()).andReturn(true); expect(account.unpaidServices()).andReturn(services); bill();

expect(rabiesVaccination.cost()).andReturn(250); expect(routineVisit.cost()).andReturn(50);

control.replay();

assertEquals(300, bill.amount()); control.verify(); }

private void bill() throws NoPaymentDueException { replay(account); bill = new Bill(account, null); verify(account); }}

23Friday, September 18, 2009

Page 45: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Coffee Vending MachineHow would you develop it?

25Friday, September 18, 2009

Page 46: Avatars Of TDD

Licensed Under Creative Commons by Naresh Jain

Where do you Stand?Unit Test x Acceptance test

API x User Interface

State x Interaction

OO x Procedural

Easy x Core

Narrow x Broad

Drive Design x Validate Design

26Friday, September 18, 2009