Test Driven Development
       Demonstrated
             Alan Christensen @christensena
              Tom Gutteridge @trgutteridge


A g ile P r o f e s s io n a ls N e t w o r k
            C h r is t c h u r c h
   Th a n k s to o u r s p o n s o r s …
2
Who am I?
Format
• Introduction Presentation
• Live coding exercise
• Review slides
• TDD in the real world
• Questions and discussion
Test Driven
                  Development
•   It is a development technique

•   Incremental (iterative) workflow

    •   Always write a failing test
        first (red)

    •   Only write the minimum
        code to pass the failing test
        (green)

    •   Improve code while all tests
        are passing (refactor)          http://www.agileapps.co.uk/methodology/continuous.html
Not about testing #1
• Yes you do end up with a suite of tests
• But TDD is a development exercise
 • my mindset is coding, not testing
 • I will not be exhausting edge cases, etc
    (at least initially)
Not about testing #2
• By practicing TDD
 • I approach my code from the outside,
    focusing on specifying behaviour
 • I can focus on one thing at a time
 • My resulting code is inherently designed
    for testability
 • I get fast feedback
Live coding exercise

• Coding Kata
• Wikipedia definition: “A code kata is an
  exercise in programming which helps hone
  your skills through practice and repetition”
TDD improves design
• Encourages separation of concerns/single
  responsibility principle (SRP)
• Incremental, iterative: can lead to simpler
  designs
• Reduces fear of refactoring, encouraging
  improvements to design
• Alerts me to design smells
Tests as documentation

• Unit test code provides numerous working
  examples of API usage
• Good unit test structure and naming can
  act as a specification
• Tests as documentation always up to date
  (or the tests are failing)
Objections to TDD
• It takes too much time
• Tests can make it harder to refactor, not
  easier
• It’s just too hard with our legacy code or
  un-mockable framework(s)
• Our test suite takes too long to run so we
  don’t run it very often
Why is TDD Hard?
• Mindset seems unnatural at first
• Many frameworks/library components
  make it difficult to verify behaviour
• Large monolithic blocks of legacy code are
  hard to isolate
• Good design is not always obvious at first
• Forgetting to test first, not afterwards!
Make TDD easier
• Practice Red-Green-Refactor discipline on
  simpler examples (e.g. katas) away from a
  real code base
• Learn from each other (e.g. weekly brown
  bag/dojo sessions), pair programming
• Learn good design, especially OO design
• Listen to your tests! If it’s getting hard
  going, consider refactoring your code
• Take it seriously!
Tips: Untestable
        Frameworks
• Use adapter pattern to "broker" untestable
  dependencies
• Adapters should be tailored to how they
  are used by the app. Adapters do not need
  to expose entire API, only what is needed
• Decouple logic from frameworks (e.g. use
  MVC pattern)
Productivity with TDD
• It takes practice to become productive
• Test code should be taken seriously, not
  treated as throwaway
• Keep duplication to a minimum but balance
  this with readability
• Worst case: your design completely
  changes resulting in rewrite. You have the
  old tests as a reference (specs)
What not to TDD?
What is a unit?

• "smallest thing that makes sense" George
  Dinwiddie
• Sometimes a method, sometimes a
  collaboration of classes
Unit vs Integration
• Unit tests
 • should be fast (fast feedback loop)
 • should be focused
 • when they fail, they usually point you to
    where problem is
  • rigorous within the component under
    test
  • one assert per test
Integration vs Unit
• Integration tests
 • usually slow
 • good for verifying unit tested
    components connect together properly
  • good for acceptance tests
  • often easier to start with on a legacy
    code base
Other Topics
• System Under Test isolation (mocks and
  stubs)
• Real World Unit Testing (or how to deal
  with existing test unfriendly code)
• Context specification (or how to write
  expressive, DRY test suites)
• Tips and Tricks, avoiding anti-patterns
Links

• String Calculator kata exercise
  http://osherove.com/tdd-kata-1/
• Bowling game kata step by step
  (Powerpoint)
  http://butunclebob.com/ArticleS.UncleBob.TheBow

TDD - Christchurch APN May 2012

  • 1.
    Test Driven Development Demonstrated Alan Christensen @christensena Tom Gutteridge @trgutteridge A g ile P r o f e s s io n a ls N e t w o r k C h r is t c h u r c h Th a n k s to o u r s p o n s o r s …
  • 2.
  • 9.
  • 10.
    Format • Introduction Presentation •Live coding exercise • Review slides • TDD in the real world • Questions and discussion
  • 11.
    Test Driven Development • It is a development technique • Incremental (iterative) workflow • Always write a failing test first (red) • Only write the minimum code to pass the failing test (green) • Improve code while all tests are passing (refactor) http://www.agileapps.co.uk/methodology/continuous.html
  • 12.
    Not about testing#1 • Yes you do end up with a suite of tests • But TDD is a development exercise • my mindset is coding, not testing • I will not be exhausting edge cases, etc (at least initially)
  • 13.
    Not about testing#2 • By practicing TDD • I approach my code from the outside, focusing on specifying behaviour • I can focus on one thing at a time • My resulting code is inherently designed for testability • I get fast feedback
  • 14.
    Live coding exercise •Coding Kata • Wikipedia definition: “A code kata is an exercise in programming which helps hone your skills through practice and repetition”
  • 15.
    TDD improves design •Encourages separation of concerns/single responsibility principle (SRP) • Incremental, iterative: can lead to simpler designs • Reduces fear of refactoring, encouraging improvements to design • Alerts me to design smells
  • 16.
    Tests as documentation •Unit test code provides numerous working examples of API usage • Good unit test structure and naming can act as a specification • Tests as documentation always up to date (or the tests are failing)
  • 17.
    Objections to TDD •It takes too much time • Tests can make it harder to refactor, not easier • It’s just too hard with our legacy code or un-mockable framework(s) • Our test suite takes too long to run so we don’t run it very often
  • 18.
    Why is TDDHard? • Mindset seems unnatural at first • Many frameworks/library components make it difficult to verify behaviour • Large monolithic blocks of legacy code are hard to isolate • Good design is not always obvious at first • Forgetting to test first, not afterwards!
  • 19.
    Make TDD easier •Practice Red-Green-Refactor discipline on simpler examples (e.g. katas) away from a real code base • Learn from each other (e.g. weekly brown bag/dojo sessions), pair programming • Learn good design, especially OO design • Listen to your tests! If it’s getting hard going, consider refactoring your code • Take it seriously!
  • 20.
    Tips: Untestable Frameworks • Use adapter pattern to "broker" untestable dependencies • Adapters should be tailored to how they are used by the app. Adapters do not need to expose entire API, only what is needed • Decouple logic from frameworks (e.g. use MVC pattern)
  • 21.
    Productivity with TDD •It takes practice to become productive • Test code should be taken seriously, not treated as throwaway • Keep duplication to a minimum but balance this with readability • Worst case: your design completely changes resulting in rewrite. You have the old tests as a reference (specs)
  • 22.
  • 23.
    What is aunit? • "smallest thing that makes sense" George Dinwiddie • Sometimes a method, sometimes a collaboration of classes
  • 24.
    Unit vs Integration •Unit tests • should be fast (fast feedback loop) • should be focused • when they fail, they usually point you to where problem is • rigorous within the component under test • one assert per test
  • 25.
    Integration vs Unit •Integration tests • usually slow • good for verifying unit tested components connect together properly • good for acceptance tests • often easier to start with on a legacy code base
  • 26.
    Other Topics • SystemUnder Test isolation (mocks and stubs) • Real World Unit Testing (or how to deal with existing test unfriendly code) • Context specification (or how to write expressive, DRY test suites) • Tips and Tricks, avoiding anti-patterns
  • 27.
    Links • String Calculatorkata exercise http://osherove.com/tdd-kata-1/ • Bowling game kata step by step (Powerpoint) http://butunclebob.com/ArticleS.UncleBob.TheBow