Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Test-Driven Development

Test-Driven Development

A presentation on TDD as I was presenting it in 2008.

Matteo Vaccari

June 03, 2008
Tweet

More Decks by Matteo Vaccari

Other Decks in Technology

Transcript

  1. Unit tests • Focus on a class, method or function

    • Run entirely in memory • Extremely fast!
  2. Unit tests run fast. A test is not a unit

    test if: 1. It talks to a database 2. It communicates across the network 3. It touches the file system 4. You have to do things to your environment to run it (eg, change config files) Tests that do this are integration tests Michael Feathers
  3. Integration tests • Unit tests prove our logic is correct

    • Integration test prove our program communicates correctly with the outside world
  4. System under test DB Billing GUI End-to-end tests • ...are

    the least convenient kind of integration tests
  5. System under test DB Billing GUI Focused integration tests •

    Each test deals with one external interaction
  6. Customer tests • Also known as “Acceptance tests” • Motto:

    We implement tricky domain concepts correctly Example from Mugridge & Cunningham Fit For Developing Software
  7. Customer tests • Customer test are customer-provided examples • Often

    captured in table form • Expressed in the language of the business • Automated Example from Mugridge & Cunningham Fit For Developing Software
  8. Clean code that works • is out of reach of

    even the best programmers, some of the time, • and out of reach of most programmers (like me) most of the time -- Kent Beck
  9. Simple design The code is simple enough when it: 0.

    Runs all the tests 1. Expresses every idea that we need to express 2. Contains no duplication 3. Has the minimum number of classes and functions (In this order) Adapted from Extreme Programming Installed by Ron Jeffries et al.
  10. Clean code that works • First we'll solve the “that

    works” part • Then we'll solve the “clean code” part
  11. [email protected] Write a test public class AdderTest { @Test public

    void testTwoPlusThree() { Adder a = new Adder(); assertEquals(5, a.add(2, 3)); } }
  12. [email protected] Now it compiles public class AdderTest { @Test public

    void testTwoPlusThree() { Adder a = new Adder(); assertEquals(5, a.add(2, 3)); } } public class Adder { public int add(int a, int b) { return 0; } }
  13. [email protected] Red bar! public class AdderTest { @Test public void

    testTwoPlusThree() { Adder a = new Adder(); assertEquals(5, a.add(2, 3)); } } public class Adder { public int add(int a, int b) { return 0; } } Expected 5, was 0
  14. [email protected] Just pretend public class AdderTest { @Test public void

    testTwoPlusThree() { Adder a = new Adder(); assertEquals(5, a.add(2, 3)); } } public class Adder { public int add(int a, int b) { return 5; } }
  15. [email protected] Remove the duplicated “5” public class AdderTest { @Test

    public void testTwoPlusThree() { Adder a = new Adder(); assertEquals(5, a.add(2, 3)); } } public class Adder { public int add(int a, int b) { return a+b; } }
  16. [email protected] The procedure 1. Write a test 2. Make it

    compile 3. Make it pass 4. Remove duplication Expected 5, was 0
  17. [email protected] Clean code, why? • Design is the great accelerator:

    • If you drop quality for speed, you will get neither • If you aim for quality... • ... and you know how to get it... • ... you will also be fast!
  18. [email protected] Test first, why? • You think code from the

    point of view of the caller • This perspective makes for better design • Test coverage is a useful byproduct
  19. [email protected] Refactor, why? • Because I can: the tests support

    refactoring • Refactoring is when I do design • I don’t claim I can guess the right design at first • Design emerges, with thought, care and small steps
  20. [email protected] Il punteggio del bowling Ci sono 10 frame. In

    ogni frame il giocatore ha due possibilità di abbattere 10 birilli (pins). Il punteggio per il frame è il numero di birilli abbattuti, più i bonus per stike o spare. Uno spare è quando il giocatore abbatte 10 birilli in due tiri. Il bonus per quel frame è il numero di birilli abbattuti al tiro successivo. Nel frame 3 dell'esempio, il punteggio è 10 (i birilli abbattuti) più il bonus di 5 (abbattuti nel tiro successivo.) Uno strike è quando il giocatore abbatte tutti i birilli in un solo tiro. Il bonus per quel frame è il numero di birilli abbattuti nei due tiri successivi Nel decimo frame, se il giocatore fa uno strike o spare può fare i tiri necessari per completare il frame. In ogni caso, al decimo frame non vengono fatti più di tre tiri.
  21. [email protected] The requirements • Write class “Game” with two methods:

    • void roll(int pins); call when the player rolls a ball. The argument is the number of pins knocked down. • int score(); called when the game is ended. Returns the final score.
  22. [email protected] Let’s think about design? • A quick object-oriented analysis

    leads us to think we need • class Game • class Frame • class Roll • class TenthFrame extending Frame • ...
  23. [email protected] Let’s think about design? • A quick object-oriented analysis

    leads us to think we need • class Game • class Frame • class Roll • class TenthFrame extending Frame • ... forget about all that!
  24. [email protected] Ancora, perché test first? • per concentrarsi su quello

    che serve veramente (no gold plating) • good enough! quando il test passa so che posso fermarmi • perché penso al codice come un cliente di questo codice • perché ottengo codice testabile, e il codice testabile • ha uno scopo preciso • è disaccoppiato dal resto del sistema • è più generale • il design emerge mano a mano che capisco meglio il problema
  25. [email protected] Ancora, perché refactoring? • simplicity is key • il

    design nel tempo si imbastardisce • fare il design prima significa farlo nel momento peggiore: quando ne so di meno • molto meglio fare design mentre sviluppo
  26. [email protected] Do the simplest thing 1. Build the quickest code

    that will pass the tests 2. Refactor the code to have the simplest design possible
  27. [email protected] What is simple design? • The code passes all

    tests • There is no duplication • The code expresses the programmer’s intention • Using the smallest number of classes and methods In this order
  28. [email protected] TDD is a key practice • Defects kill predictability

    no predictability, no planning! • Test-driven is predictable • Hardly ever use the debugger
  29. [email protected] No silver bullet • Needs lots of practice •

    Requires discipline • Must think and be alert at all times!
  30. Supermarket checkout • Compute the total price • Scan items

    one at a time • In any order Source: Dave Thomas, http://codekata.pragprog.com/2007/01/kata_nine_back_.html