An Introduction to Test Driven Development Julian Zappala - PowerPoint PPT Presentation

1 / 30
About This Presentation
Title:

An Introduction to Test Driven Development Julian Zappala

Description:

Data from industry experience suggests we might expect, on average, 15 to 50 ... McConnell, Steven C. Code Complete: A practical handbook of software construction. ... – PowerPoint PPT presentation

Number of Views:120
Avg rating:3.0/5.0
Slides: 31
Provided by: julianz
Category:

less

Transcript and Presenter's Notes

Title: An Introduction to Test Driven Development Julian Zappala


1
An Introduction to Test Driven DevelopmentJulian
Zappala
2
Why test at all?
  • As software developers we are only human
  • It's inevitable that we'll make mistakes
  • Data from industry experience suggests we might
    expect, on average, 15 to 50 errors per 1000
    lines of source code
  • McConnell, Steven C.
  • Code Complete A practical handbook of software
    construction.
  • 2nd ed. Microsoft Press, 2004.

3
Typical Software Development
  • CODE FIRST... then test (hopefully...)?
  • Developer testing activities often include
  • Unit Testing Does the new unit work by itself?
  • Integration Testing Does the new unit work with
    other units?
  • Regression Testing Does the new unit break
    other units which used to work?
  • These are distinct from other testing roles
  • Functional Testing e.g. User Acceptance Testing
  • Non-functional Testing e.g. Performance,
    Usability, Scalability, Security etc...

4
About Test Driven Development
  • A different approach to Designing, Developing and
    Testing software
  • Conceived by Kent Beck as part of eXtreme
    Programming
  • Increasingly popular as part of many Agile
    methodologies
  • Often achieved through the use of a unit testing
    framework such as the xUnit family
  • A unit is single, atomic, software component
    typically this means a class

5
Steps in Test Driven Development
  • TEST FIRST... then code
  • First write a test for some, typically very
    small, unit of code
  • The test will fail as the code is not yet written
  • Write just enough code such that the test should
    pass
  • Test again to be sure that the new (and any
    existing tests) pass
  • Refactor make sure the new code is tidy
  • Repeat

6
Implications of Test Driven Development
  • By writing the test first, the initial focus is
    on how we'd like to use a class rather than how
    we'd like to make the class
  • This approach encourages Coding by Intention
  • By running tests frequently we can be more
    confident about the quality of our work
  • By using automated testing tools we can discover
    early on if new code introduces integration or
    regression issues
  • Let's look at an example...

7
Example Use Case
Roll Dice
Preconditions The actor has a n-sided fair
dice Steps 1. The actor rolls the
dice Postconditions The actor has a random
number between 1 and the number of sides
8
A naive design for the Dice Class
Dice
- numSides int - faceValue int
getNumSides() int setNumSides(numSides
int) void getFaceValue() int roll() void
Would anyone care to comment on the design of
this class?
9
Some Issues in the naive design
  • It is possible to invoke roll without first
    setting the number of sides
  • It is possible to invoke getFaceValue without
    first invoking roll (or setting the number of
    sides)?
  • It is possible to change the number of sides that
    a dice has (!)?
  • etc...
  • So, can TDD give us a better design?

10
TDD Step 1 Write a test
  • But what test?
  • How about instantiation?
  • OK we're going to make a new dice how many
    sides will it have?
  • What can we test? - Maybe that we have an
    object...

public void testDiceConstructor() Dice d
new Dice(6) assertNotNull(d)
11
TDD Step 2 Fail the Test
  • Attempt to run the test
  • The test will fail in fact it won't even
    compile because we haven't created the Dice class
    yet
  • Error Dice cannot be resolved to a type
  • This counts as a failure in TDD
  • Now that we have a test that fails it's time to
    write some code...

12
TDD Step 3 Write just enough code
  • We are only concerned with passing the test, so

public class Dice Dice(int numSides)

13
TDD Step 4 Test Again
  • This time the test passes!

14
TDD Step 5 Refactor
  • Refactoring is a disciplined technique for
    restructuring an existing body of code, altering
    its internal structure without changing its
    external behavior.
  • Fowler, Martin
  • http//www.refactoring.com/
  • There isn't much to refactor at this stage, so
    let's press on...

15
Repeat From Step 1
  • Write a test How many sides does the dice have?
  • public void testDiceSixSides()
  • Dice d new Dice(6)
  • assertEquals(6,d.getNumSides())
  • The test fails (will not compile) as there is no
    getNumSides method...

16
Writing Just Enough code...
  • To pass the test we only need
  • public int getNumSides()
  • return 6
  • Run the test - This will pass the test
  • There's still no requirement to refactor
  • So let's write another test

17
Another Test...
  • What about a ten sided dice?
  • public void testDiceTenSides()
  • Dice d new Dice(10)
  • assertEquals(10,d.getNumSides())

18
Which Fails...
19
So we (try to) fix it...
  • We could just return 10 from getNumSides() but
    that would break the test for Six sides, so...
  • public class Dice
  • private int numSides
  • Dice(int numSides)
  • this.numSides numSides
  • public int getNumSides()
  • return numSides

20
That passes - Great!
21
Choose your tests carefully...
  • Let's test something that shouldn't happen
  • This is sometimes referred to as
  • Test what might break
  • Ever heard of a one sided dice?
  • public void testDiceOneSide()
  • Dice d new Dice(1)
  • assertTrue("No One Sided Dice!",
  • 1 ! d.getNumSides())

22
Good - That fails too!
Assume that we fix this (and pass the
test)? Let's move on...
23
Yet Another Test
  • Assuming we're confident that we can now make a
    good dice, let's try rolling it...
  • public void testRollSixSides()
  • Dice d new Dice(6)
  • int v d.roll()
  • assertTrue("Not Between 1 and 6",
  • (v gt 1) (v lt 6))

24
Write some more code...
  • Just enough code to pass could be
  • public int roll()
  • return 5
  • That passes the test too!
  • Let's see where we're at...

25
The Test Driven Development Dice
Dice
- numSides int
Dice(numSides int) this roll() int
Compare to the naive Dice
Dice
- numSides int - faceValue int
getNumSides() int setNumSides(numSides
int) void getFaceValue() int roll() void
26
Can we test that the Dice is fair ?
  • Testing things that are unpredictable is very
    hard. In software there are many things that are
    unpredictable e.g.
  • Data in a database, Networks and network
    resources
  • Other software developers
  • Typically anything beyond the boundary of the
    unit that is being tested
  • One solution to this is to use Mock Objects
    when testing

27
About Mock Objects
  • Used in unit testing where an action does not
    have a guaranteed result
  • One solution is to define the action(s) through
    an interface
  • In testing circumstances we use a Mock Object to
    implement the interface, for production code use
    the real object
  • The real object can be tested through (automated)
    integration testing at some later stage

28
Summary Some ve's of TDD
  • Coding by intention can produce clearer, simpler
    code
  • Focusing on one thing (the failed test) can make
    programming more efficient and reduce time spent
    debugging
  • Making classes that are Unit Testable typically
    means that the overall system is more Modular and
    more Loosely Coupled
  • Every unit of code is tested and so should be
    more robust and contain less errors

29
Summary Some -ve's of TDD
  • Writing the tests means there is more code to
    write, maintain and debug
  • Managers often find this hard to come to terms
    with
  • Writing the right tests isn't always easy, and
    wrong tests lead to wrong code
  • Although 100 testing coverage is possible even
    this may not exercise every code-path
  • TDD is not a panacea for testing

30
Further Reading/Resources
  • Test Driven Development By Example
  • Kent Beck
  • Addison-Wesley (2002)?
  • Refactoring Improving the design of existing
    code
  • Fowler, Beck, Brant, Opdyke, Roberts
  • Addison-Wesley (1999)?
  • JUnit
  • http//www.junit.org/
Write a Comment
User Comments (0)
About PowerShow.com