Behaviour Driven Development  and thinking about testing           Malcolm Tredinnick      malcolm.tredinnick@gmail.com
Why have I asked you here today?     1) Testing landscape     2) A different way to think about this     3) Code
Chapter I: The Testing Landscape
Isolated   Integrated
Isolated                           Integrated        Testing unit            External service           size?             ...
Mocks●   Substitute for external systems & components●   Need to be injected into the tests    ●   “Monkey patching”    ● ...
Monkey patchingimport socketdef setUp(...):   socket.socket = DummySocketObject   ...
Mocks●   Substitute for external systems & components●   Need to be injected into the tests    ●   “Monkey patching”    ● ...
Isolated                    Integrated           Infrastructure
ce                                     n                                e na                             nt               ...
Testing Strategies   Some of many...
Testing Strategies●   Formal verification
Testing Strategies●   Formal verification●   Test everything you can think of
Testing Strategies●   Formal verification●   Test everything you can think of●   Anti-regression suite      No bug fix wit...
Testing Strategies●   Formal verification●   Test everything you can think of●   Anti-regression suite●   Test driven deve...
TDD1.Write a (failing) test for next method or class2.Write minimal code to make test pass3.Rinse, wash, repeat.
Testing Strategies●   Formal verification●   Test everything you can think of●   Anti-regression suite●   Test driven deve...
Testing Strategies●   Formal verification●   Test everything you can think of●   Anti-regression suite●   Test driven deve...
Testing Strategies●   Formal verification●   Test everything you can think of●   Anti-regression suite●   Test driven deve...
Chapter II: A different way of thinking
Interlude: Creating systems...
Interlude: Creating systems...          Specification
Interlude: Creating systems...        Specification                    Implementation         Testing
Specification●   On (e-)paper?    ●   quick sketch    ●   formal requirements document    ●   mailing list discussion●   I...
Specification●   Capturing the idea is probably good●   “What was I thinking smoking when...?”
SpecificationAs a [user or role],I want [feature]so that [something happens]
SpecificationAs a maze creator,I want to be able to specify dimensionsso that a new maze of the given size is created.
BDDWhat is the next most importantthing the code should do?
BDD     What is the next most important     thing the code should do?Be able totest this...              ... then implemen...
ScenarioGiven that [initial context],if and when [some event occurs]then [ensure some outcomes]
Use case versus scenarioAs a [user or role],          Given that [initial context],I want [feature]              if and wh...
Chapter III: Concrete code
Interlude: Naming things Language helps guide our brain. Focuses the mind. Perhaps too exclusively.
Interlude: Naming thingsThe Sapir-Whorf Hypothesis:“[...] the structure of a language affects the ways inwhich its speaker...
Example #1: Pythons unittest module
Test titlesclass BasicFieldTests (TestCase):  def test_field_name (self):    ...  def test_show_hidden_initial (self):    ...
Test titlesclass Fields (TestCase):  def should_allow_name_override (self):     ...class ChoiceFields (TestCase):  def sho...
Run new test titlesWrite a load_test() method to pull outall the “should” methods.(Easy enough, but a few lines of code.)
Matching to scenarios●   Typically, end up creating more classes than    unittests (not a bad thing; classes are “free”). ...
Example #2: Doctests
Narrative style testingJane created a new maze with a small (5 x 5) size.>>> from maze import Maze>>> maze = Maze(5, 5)Spo...
Narrative style testing●   Excellent if you are truly writing a narrative.●   Can be difficult to maintain (but not always...
Example #3: Domain specific languages
DSL packages●   Lettuce●   Freshen                  Both available through PyPI
Freshen exampleScenario: Divide regular numbers  Given I have entered 3 into the calculator  And I have entered 2 into the...
Backing codefrom freshen import *import calculator@Beforedef before(unused):    scc.calc = calculator.Calculator()    scc....
Backing code@When("I press (w+)")def press(button):    op = getattr(scc.calc, button)    scc.result = op()@Then("the resul...
Freshen templated exampleScenario Outline: Add two numbers  Given I have entered <input_1> into the calculator  And I have...
Conclusions(?)●   Behavioural tests are worth trying●   Question the way you think from time to time●   Are your tests pur...
https://github.com/malcolmt/bdd-and-testing-talk            malcolm.tredinnick@gmail.com                     @malcolmt
Upcoming SlideShare
Loading in …5
×

Behaviour Driven Development and Thinking About Testing

1,149 views
1,051 views

Published on

KiwiPyCon2011, Wellington, Saturday, Track 2, Behaviour Driven Development and Thinking About Testing by Malcolm Tredinnick

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,149
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
18
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Behaviour Driven Development and Thinking About Testing

  1. 1. Behaviour Driven Development and thinking about testing Malcolm Tredinnick malcolm.tredinnick@gmail.com
  2. 2. Why have I asked you here today? 1) Testing landscape 2) A different way to think about this 3) Code
  3. 3. Chapter I: The Testing Landscape
  4. 4. Isolated Integrated
  5. 5. Isolated Integrated Testing unit External service size? availabilityMocks Running time?
  6. 6. Mocks● Substitute for external systems & components● Need to be injected into the tests ● “Monkey patching” ● Dependency injection
  7. 7. Monkey patchingimport socketdef setUp(...): socket.socket = DummySocketObject ...
  8. 8. Mocks● Substitute for external systems & components● Need to be injected into the tests ● “Monkey patching” ● Dependency injection● Need to be kept in synch with reality!
  9. 9. Isolated Integrated Infrastructure
  10. 10. ce n e na nt ai MIsolated Integrated Infrastructure
  11. 11. Testing Strategies Some of many...
  12. 12. Testing Strategies● Formal verification
  13. 13. Testing Strategies● Formal verification● Test everything you can think of
  14. 14. Testing Strategies● Formal verification● Test everything you can think of● Anti-regression suite No bug fix without a test
  15. 15. Testing Strategies● Formal verification● Test everything you can think of● Anti-regression suite● Test driven development (TDD)
  16. 16. TDD1.Write a (failing) test for next method or class2.Write minimal code to make test pass3.Rinse, wash, repeat.
  17. 17. Testing Strategies● Formal verification● Test everything you can think of● Anti-regression suite● Test driven development (TDD) “Specification, not verification”
  18. 18. Testing Strategies● Formal verification● Test everything you can think of● Anti-regression suite● Test driven development (TDD)● Documentation driven development (DDD?)
  19. 19. Testing Strategies● Formal verification● Test everything you can think of● Anti-regression suite● Test driven development (TDD)● Documentation driven development (DDD?)● Behaviour driven development (BDD)
  20. 20. Chapter II: A different way of thinking
  21. 21. Interlude: Creating systems...
  22. 22. Interlude: Creating systems... Specification
  23. 23. Interlude: Creating systems... Specification Implementation Testing
  24. 24. Specification● On (e-)paper? ● quick sketch ● formal requirements document ● mailing list discussion● In your head?
  25. 25. Specification● Capturing the idea is probably good● “What was I thinking smoking when...?”
  26. 26. SpecificationAs a [user or role],I want [feature]so that [something happens]
  27. 27. SpecificationAs a maze creator,I want to be able to specify dimensionsso that a new maze of the given size is created.
  28. 28. BDDWhat is the next most importantthing the code should do?
  29. 29. BDD What is the next most important thing the code should do?Be able totest this... ... then implement it.
  30. 30. ScenarioGiven that [initial context],if and when [some event occurs]then [ensure some outcomes]
  31. 31. Use case versus scenarioAs a [user or role], Given that [initial context],I want [feature] if and when [some event occurs]so that [something happens] then [ensure some outcomes]
  32. 32. Chapter III: Concrete code
  33. 33. Interlude: Naming things Language helps guide our brain. Focuses the mind. Perhaps too exclusively.
  34. 34. Interlude: Naming thingsThe Sapir-Whorf Hypothesis:“[...] the structure of a language affects the ways inwhich its speakers are able to conceptualise theirworld [view].”
  35. 35. Example #1: Pythons unittest module
  36. 36. Test titlesclass BasicFieldTests (TestCase): def test_field_name (self): ... def test_show_hidden_initial (self): ...
  37. 37. Test titlesclass Fields (TestCase): def should_allow_name_override (self): ...class ChoiceFields (TestCase): def should_permit_initial_values_in_hidden_widgets (self): ...
  38. 38. Run new test titlesWrite a load_test() method to pull outall the “should” methods.(Easy enough, but a few lines of code.)
  39. 39. Matching to scenarios● Typically, end up creating more classes than unittests (not a bad thing; classes are “free”). ● Thinking about test names helps with class names and roles.● Context setup is done in setUp() method.● Normal unittest assertions work fairly cleanly.
  40. 40. Example #2: Doctests
  41. 41. Narrative style testingJane created a new maze with a small (5 x 5) size.>>> from maze import Maze>>> maze = Maze(5, 5)Spot, her dog, did not think the new maze was the right size, butJane was able to convince him like this:>>> maze.x_size5>>> maze.y_size5They found the entry and exit locations in their new maze:>>>maze.entry_cell(0, 0, “left”)(etc)
  42. 42. Narrative style testing● Excellent if you are truly writing a narrative.● Can be difficult to maintain (but not always).● Avoid if large amounts of setup required.● Use with caution. Do use. Do not abuse.
  43. 43. Example #3: Domain specific languages
  44. 44. DSL packages● Lettuce● Freshen Both available through PyPI
  45. 45. Freshen exampleScenario: Divide regular numbers Given I have entered 3 into the calculator And I have entered 2 into the calculator When I press divide Then the result should be 1.5 on the screen (Code samples from Freshen documentation)
  46. 46. Backing codefrom freshen import *import calculator@Beforedef before(unused): scc.calc = calculator.Calculator() scc.result = None@Given("I have entered (d+) into the calculator")def enter(num): scc.calc.push(int(num)) (Code samples from Freshen documentation)
  47. 47. Backing code@When("I press (w+)")def press(button): op = getattr(scc.calc, button) scc.result = op()@Then("the result should be (.*) on the screen")def check_result(value): assert_equal(str(scc.result), value) (Code samples from Freshen documentation)
  48. 48. Freshen templated exampleScenario Outline: Add two numbers Given I have entered <input_1> into the calculator And I have entered <input_2> into the calculator When I press <button> Then the result should be <output> on the screenExamples: | input_1 | input_2 | button | output | | 20 | 30 | add | 50 | | 2 | 5 | add | 7 | | 0 | 40 | add | 40 | (Code samples from Freshen documentation)
  49. 49. Conclusions(?)● Behavioural tests are worth trying● Question the way you think from time to time● Are your tests purpose clear to future you?
  50. 50. https://github.com/malcolmt/bdd-and-testing-talk malcolm.tredinnick@gmail.com @malcolmt

×