test driven development tdd. testing ”testing can never demonstrate the absence of errors in...

34
Test Driven Test Driven Development Development TDD TDD

Upload: alexander-carson

Post on 25-Dec-2015

220 views

Category:

Documents


0 download

TRANSCRIPT

Test Driven DevelopmentTest Driven Development

TDDTDD

TestingTesting

””Testing can never demonstrate the Testing can never demonstrate the absence of errors in software, only absence of errors in software, only their presence”their presence”

Edsger W. DijkstraEdsger W. Dijkstra

(but it is very good at the latter).(but it is very good at the latter).

TestingTesting

““If it's worth building, it's worth If it's worth building, it's worth testing.testing.

If it's not worth testing, why are you If it's not worth testing, why are you wasting your time working on it?”wasting your time working on it?”

(http://www.agiledata.org/essays/(http://www.agiledata.org/essays/tdd.html)tdd.html)

TDDTDD

Test-first or test-driven development Test-first or test-driven development has origins in eXtreme Programming has origins in eXtreme Programming (XP)(XP)

It is one part of XP that can be It is one part of XP that can be extracted and used on its ownextracted and used on its own

eXtreme ProgrammingeXtreme Programming

Is a methodology for software Is a methodology for software developmentdevelopment

Focuses on the customerFocuses on the customer

Has rules for:Has rules for:– PlanningPlanning– DesigningDesigning– CodingCoding– TestingTesting

TDD is also embraced by:TDD is also embraced by:

Rational Unified Process (RUP) Rational Unified Process (RUP)

Agile Unified Process (AUP) Agile Unified Process (AUP)

Open Unified Process (Open UP) Open Unified Process (Open UP)

ScrumScrum

(agile methods)(agile methods)

TDDTDD

Is NOT a testing methodologyIs NOT a testing methodology

It IS a development methodologyIt IS a development methodology

Does not replace QA or thorough Does not replace QA or thorough testingtesting

MethodologyMethodology

TDD TestsTDD Tests

Are only part of the development Are only part of the development processprocess

Not intended to aggressively find bugsNot intended to aggressively find bugs

They’re weakThey’re weak

A programmer taking a TDD approach A programmer taking a TDD approach refuses to write a new function until refuses to write a new function until there is first a test that fails because there is first a test that fails because that function isn’t present that function isn’t present

What are the purposes of a test?What are the purposes of a test?

Does the code work?Does the code work?– What do we mean by work?What do we mean by work?

Make sure that changes don’t break Make sure that changes don’t break anything that is already workinganything that is already working

Documents featuresDocuments features

Measure of completenessMeasure of completeness

Advantages of writing tests firstAdvantages of writing tests firstQuick results: Quick results: Developers can see the effect of Developers can see the effect of design decisions within minutes. design decisions within minutes. Flexibility: Flexibility: Changes are easy because of the short Changes are easy because of the short distance between commits. distance between commits. Automatic catalog of regression tests: Automatic catalog of regression tests: If If something developed six months ago suddenly something developed six months ago suddenly breaks under today's code, it is known breaks under today's code, it is known immediately. immediately. Good, clean code that works: Good, clean code that works: As the mantra of As the mantra of JUnit testing proclaims, "If the light is green, the JUnit testing proclaims, "If the light is green, the code is clean." code is clean."

(www.developer.com)(www.developer.com)

Disadvantages of writing tests firstDisadvantages of writing tests first

Doesn’t work well for GUIs or multi-Doesn’t work well for GUIs or multi-threaded applicationsthreaded applications

Impractical for use with legacy codeImpractical for use with legacy code

Effect or Side-effect?Effect or Side-effect?

Documentation/specificationDocumentation/specification– This group of tests you have written This group of tests you have written

becomes part of your documentation.becomes part of your documentation.– They are a list of behaviors that you They are a list of behaviors that you

have shown work.have shown work.– List of tests might not be exhaustive but List of tests might not be exhaustive but

does document what HAS been tested.does document what HAS been tested.

DocumentationDocumentation

Design specification?Design specification?– Tests are not sufficient but definitely an Tests are not sufficient but definitely an

important partimportant part

Requirements documentation?Requirements documentation?– Not part of requirementsNot part of requirements– Acceptance testing helps with Acceptance testing helps with

requirements documentationrequirements documentation

Good Unit TestsGood Unit TestsRun fast (they have short setups, run Run fast (they have short setups, run times, and break downs). times, and break downs). Run in isolation (you should be able to Run in isolation (you should be able to reorder them). reorder them). Use data that makes them easy to read Use data that makes them easy to read and to understand. and to understand. Use real data (e.g. copies of production Use real data (e.g. copies of production data) when they need to. data) when they need to. Represent one step towards your overall Represent one step towards your overall goal. goal.

(Kent Beck – creator eXtreme Programming)(Kent Beck – creator eXtreme Programming)

Test FirstTest First

Give an exampleGive an example

Write test caseWrite test case

Write code – just enough to pass the Write code – just enough to pass the testtest

Run testRun test

(fail) Repeat (goto “write code”)(fail) Repeat (goto “write code”)

(pass) Refactor code or write new test(pass) Refactor code or write new test

(how do we decide which to do?)(how do we decide which to do?)

Writing a testWriting a testWhat should the code do?What should the code do?How can you tell if it does it?How can you tell if it does it?What does reasonable input look What does reasonable input look like?like?What does UNreasonable input look What does UNreasonable input look like?like?

What about side effects? How do we What about side effects? How do we test for them?test for them?

Side-effects?Side-effects?

Good code should not have side Good code should not have side effectseffects

Your methods (functions) should do Your methods (functions) should do one thing onlyone thing only

TDD won’t test of side-effectsTDD won’t test of side-effects

What should your code do?What should your code do?

What are the input parameters?What are the input parameters?

What is the expected result?What is the expected result?

How do you know if it works?How do you know if it works?

Write a test to see if it works “as Write a test to see if it works “as expected”expected”

Run the test.Run the test.

Rewrite the code.Rewrite the code.

““as expected”as expected”

What do you expect it to do?What do you expect it to do?

What about bad inputs?What about bad inputs?– Out of range valuesOut of range values– Uninitialized values? (pointers)Uninitialized values? (pointers)

Assertions vs error-handling codeAssertions vs error-handling code

Error handling codeError handling code

Conditions you expect to occurConditions you expect to occur

Consider how much this particular Consider how much this particular piece of code is protected from bad piece of code is protected from bad input in useinput in use– Is it a private method?Is it a private method?– Should it be?Should it be?

AssertionsAssertionsassert()assert()

These are used during development These are used during development in your CODE, not your tests.in your CODE, not your tests.

Use for conditions you expect NEVER Use for conditions you expect NEVER to occur.to occur.

ConsiderConsider(an extremely simple example)(an extremely simple example)

A function to divide one number by anotherA function to divide one number by another

r = div(num,den);r = div(num,den);

Test1:Test1:r = div(4,3);r = div(4,3);

Run Test1:Run Test1:r = 1r = 1

What did we learn?What did we learn?

Div: Test1Div: Test1What did we learn?What did we learn?

Div returns an INTDiv returns an INT

Is that what we want?Is that what we want?

Div: Test1 (again)Div: Test1 (again)We’ve changed to code to return float.We’ve changed to code to return float.(This is the only change we make! (This is the only change we make!

Why?)Why?)

r = div(4, 3);r = div(4, 3);r = 1.333333;r = 1.333333;

Pass: refactor or new test?Pass: refactor or new test?(how do we decide?)(how do we decide?)

Div: Test2Div: Test2

What should we test?What should we test?

Div: Test2Div: Test2(6 new tests)(6 new tests)

What should we test?What should we test?– NegativeNegative

DividendDividend

DivisorDivisor

BothBoth

– 0 0 DividendDividend

DivisorDivisor

BothBoth

Div: Test2Div: Test2How about divide by 0?How about divide by 0?

r = div(4, 3);r = div(4, 3);r = div(5.0, 0.0);r = div(5.0, 0.0);

(notice that I still run test 1)(notice that I still run test 1)

Should divide by zero be handled by an Should divide by zero be handled by an assertion or by error handling code?assertion or by error handling code?

What have we accomplished?What have we accomplished?

We have refined the definition of “div”We have refined the definition of “div”

We have tests that we know our code We have tests that we know our code passespasses

We’ve documented some of the We’ve documented some of the behavior of “div”behavior of “div”

When something fails in the future, we When something fails in the future, we have a list of tests. We can look to see have a list of tests. We can look to see if there are new tests that need to be if there are new tests that need to be written.written.

Example: Calculate EW RatioExample: Calculate EW RatioWe can approximate the ratio of the We can approximate the ratio of the distance between elevations EW as distance between elevations EW as compared to NS as cos(latitude)compared to NS as cos(latitude)Requirement:Requirement:– Integer where 1 unit = 1/1000 arc Integer where 1 unit = 1/1000 arc

second per unitsecond per unit– Example:Example:

N40 12 42.018 = (40*3600 + 12*60 + N40 12 42.018 = (40*3600 + 12*60 + 42.018)*100042.018)*1000=144762018=144762018

EWScalingEWScaling

Things to test for:Things to test for:– Magnitude of inputMagnitude of input– Range:Range:

-90 – 90 degrees-90 – 90 degrees

Latitudes above 90 and below -90Latitudes above 90 and below -90– What behavior should it have?What behavior should it have?– The tests should reflect your DEFINITION of the The tests should reflect your DEFINITION of the

behavior and should help you refine the definitionbehavior and should help you refine the definition

TestsTests

Ratio = EWScaling(0);Ratio = EWScaling(0); // 1.0// 1.0

Ratio = EWScaling(90*3600*1000); // Ratio = EWScaling(90*3600*1000); // 0.00.0

Ratio = EWScaling(60*3600*1000); // Ratio = EWScaling(60*3600*1000); // 0.50.5

To employ TDDTo employ TDDYou design organically, with the running code You design organically, with the running code providing feedback between decisions. providing feedback between decisions. You write your own tests because you can't wait 20 You write your own tests because you can't wait 20 times per day for someone else to write them for times per day for someone else to write them for you. you. Your development environment must provide rapid Your development environment must provide rapid response to small changes (e.g you need a fast response to small changes (e.g you need a fast compiler and regression test suite). compiler and regression test suite). Your designs must consist of highly cohesive, loosely Your designs must consist of highly cohesive, loosely coupled components (e.g. your design is highly coupled components (e.g. your design is highly normalized) to make testing easier (this also makes normalized) to make testing easier (this also makes evolution and maintenance of your system easier evolution and maintenance of your system easier too). too).

(Beck)(Beck)