Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Introduction to BDD (Behavior-Driven Development)

43 views

Published on

An Introduction to Behavior-Driven Development (BDD) with Python and Behave

Published in: Software
  • Be the first to like this

Introduction to BDD (Behavior-Driven Development)

  1. 1. INTRODUCTION TO BDDINTRODUCTION TO BDD BEHAVIOR DRIVEN DEVELOPMENTBEHAVIOR DRIVEN DEVELOPMENT 1
  2. 2. 2 . 1
  3. 3. whoamiwhoami Juan Ignacio Rodríguez de león @jileon en Twitter Backend developer en OctopusLabs 2 . 2
  4. 4. WE ARE HIRINGWE ARE HIRING More info at: https://octopuslabs.com/careers 2 . 3
  5. 5. HOW IS THIS TALK STRUCTURED?HOW IS THIS TALK STRUCTURED? Presentation (Finished!) Teory Practice Libraries, tools, recomendations... 2 . 4
  6. 6. THEORYTHEORY 3 . 1
  7. 7. In theory, there is no difference between theory and practice. In practice, there is. -- Benjamin Brewster 3 . 2
  8. 8. WHAT IS BDDWHAT IS BDD As stated by wikipedia: ... an extension of TDD that makes use of a simple, domain-specific scripting language structured like natural language statements to ensures all development projects remain focused on delivering what the business actually needs while meeting all requirements. 3 . 3
  9. 9. manman WATH IS BDDWATH IS BDD As stated by wikipedia: ... an extension of TDD that makes use of a simple, domain-specific scripting language structured like natural language statements to ensures all development projects remain focused on delivering what the business actually needs while meeting all requirements. 3 . 4
  10. 10. TLDRTLDR They are tests. As in TDD, we use test to drive the design of the so ware Usually, on a higher level than TDD Written in a natural lenguage , like English Example 3 . 5
  11. 11. TLDRTLDR They are tests. As in TDD, we use test to drive the design of the so ware Usually, on a higher level than TDD Written in a natural lenguage , like English Example 3 . 5
  12. 12. TLDRTLDR They are tests. As in TDD, we use test to drive the design of the so ware Usually, on a higher level than TDD Written in a natural lenguage , like English Example 3 . 5
  13. 13. TLDRTLDR They are tests. As in TDD, we use test to drive the design of the so ware Usually, on a higher level than TDD Written in a natural lenguage , like English Example 3 . 5
  14. 14. TARGET: SHARE KNOWLEDGETARGET: SHARE KNOWLEDGE A natural lenguaje: Is used for all of us Everyone can define, debate o improve a test Allow all the team to discuss on tipically conflictive topics: edge cases, exceptions... 3 . 6
  15. 15. TARGET: SHARE KNOWLEDGETARGET: SHARE KNOWLEDGE A natural lenguaje: Is used for all of us Everyone can define, debate o improve a test Allow all the team to discuss on tipically conflictive topics: edge cases, exceptions... 3 . 6
  16. 16. TARGET: SHARE KNOWLEDGETARGET: SHARE KNOWLEDGE A natural lenguaje: Is used for all of us Everyone can define, debate o improve a test Allow all the team to discuss on tipically conflictive topics: edge cases, exceptions... 3 . 6
  17. 17. TARGET: SHARE KNOWLEDGETARGET: SHARE KNOWLEDGE A natural lenguaje: Is used for all of us Everyone can define, debate o improve a test Allow all the team to discuss on tipically conflictive topics: edge cases, exceptions... 3 . 6
  18. 18. EXECUTABLE SPECIFICATIONSEXECUTABLE SPECIFICATIONS Using this test as specifications for our so ware, we get specifications written on a plain english, but executables. 3 . 7
  19. 19. EXECUTABLE SPECIFICATIONSEXECUTABLE SPECIFICATIONS Using this test as specifications for our so ware, we get specifications written on a plain english, but executables. 3 . 7
  20. 20. HOW CAN YOU "EXECUTE" ENGLISH?HOW CAN YOU "EXECUTE" ENGLISH? Transform a plain english specification in a test Example 3 . 8
  21. 21. NOW WE HAVE TESTS!NOW WE HAVE TESTS! But, obviously, we need to implement the code. No black magic Before that, lets review a few details about files and organization. 3 . 9
  22. 22. GHERKINGHERKIN The format used in this specification is called Gherkin There are just a few words that have a special meaning: Feature, Scenario, Given, When y Then. (Also And, But) 3 . 10
  23. 23. FEATUREFEATURE Every feature is a capacity of our product. Each feature must have its own .feature file The keyword Feature must go at the begining, and gives us the opportunity to descrive the feature in one line The rest of text between the feature line and the first scenario can be used to describe the feature with more detail 3 . 11
  24. 24. SCENARIOSCENARIO Usually, a feature has more than one scenario, because we are interested on testing diferent aspects: changing conditiones, edge cases, different inputs, etc... Every diferent case is defined with the keyboard Scenario As a rule, every scenario is a complete and concrete example of a feature 3 . 12
  25. 25. GIVENGIVEN Given put our system in a known and controled state, before the first intereaction. (No user interactions if this part) 3 . 13
  26. 26. WHENWHEN When This is where we describe the actions the user or external system wants to do. This must yield some changes in the system. Or maybe not 3 . 14
  27. 27. THENTHEN Then This is where we check that the outcomes of our system are the expected 3 . 15
  28. 28. AND Y BUTAND Y BUT And y But are alternative versions of Given and Then just to get a better feeling of proper english. So, instead of writing: We can write: Given I have 10000€ in my current acount Given I have 300€ in my saving accout Given I have 10000€ in my current acount And I have 300€ in my saving accout 3 . 16
  29. 29. GO BACK TO PRACTICEGO BACK TO PRACTICE LETS IMPLEMENT THE TESTLETS IMPLEMENT THE TEST Example 3 . 17
  30. 30. A FEW INTERESTING DETAILSA FEW INTERESTING DETAILS ON STEPSON STEPS The name of the function used to implemente the steps it's not important! Behave decide what funciones to call, and when, based only in the text of decorator Main idea is having reusable steps 3 . 18
  31. 31. A FEW INTERESTING DETAILSA FEW INTERESTING DETAILS ON STEPSON STEPS The name of the function used to implemente the steps it's not important! Behave decide what funciones to call, and when, based only in the text of decorator Main idea is having reusable steps 3 . 18
  32. 32. A FEW INTERESTING DETAILSA FEW INTERESTING DETAILS ON STEPSON STEPS The name of the function used to implemente the steps it's not important! Behave decide what funciones to call, and when, based only in the text of decorator Main idea is having reusable steps 3 . 18
  33. 33. REQUESTREQUEST Every step has a common first parameter called request, that could be used for Sharing data This data can be shared at a feaure level or a scenario level 3 . 19
  34. 34. REQUESTREQUEST Every step has a common first parameter called request, that could be used for Sharing data This data can be shared at a feaure level or a scenario level 3 . 19
  35. 35. PARAMETER CAPTUREPARAMETER CAPTURE One interesting ability is to "capture" some part of the text of the step This allow us to have parametrizable, and hence, more reusable steps Lets see this with another example 3 . 20
  36. 36. DIFFERENCES WITH TDDDIFFERENCES WITH TDD Emphasis is not in the code, but in the functionality Specification is written in natural language (i.e. english) Spoken by all the members of the team: Developers testers, Q/A, product owners, skateholders, users... 3 . 21
  37. 37. DIFFERENCES WITH TDDDIFFERENCES WITH TDD Emphasis is not in the code, but in the functionality Specification is written in natural language (i.e. english) Spoken by all the members of the team: Developers testers, Q/A, product owners, skateholders, users... 3 . 21
  38. 38. DIFFERENCES WITH TDDDIFFERENCES WITH TDD Emphasis is not in the code, but in the functionality Specification is written in natural language (i.e. english) Spoken by all the members of the team: Developers testers, Q/A, product owners, skateholders, users... 3 . 21
  39. 39. DIFFERENCES WITH TDDDIFFERENCES WITH TDD Emphasis is not in the code, but in the functionality Specification is written in natural language (i.e. english) Spoken by all the members of the team: Developers testers, Q/A, product owners, skateholders, users... 3 . 21
  40. 40. PRACTICEPRACTICE 4 . 1
  41. 41. A FEATURE FILE EXAMPLEA FEATURE FILE EXAMPLE 4 . 2
  42. 42. Feature: Transfer between accounts Scenario: Add savings Given I have 10.000€ in my current acount And I have 300€ in my saving accout When I transfer 200€ from current to saving Then I should have 9.800€ in my current acount And I should have 500€ in my saving acount ◀ 4 . 3
  43. 43. INSTALL BEHAVEINSTALL BEHAVE Behave is a BDD tool written in Python We will see other options for other languages at the end of the talk 4 . 4
  44. 44. pip install behave 4 . 5
  45. 45. FOR OUR FIRST BDD TEST...FOR OUR FIRST BDD TEST... WE ARE GOING TO NEED ...WE ARE GOING TO NEED ... A features directory Inside: a directory named steps. And a file named with extension .feature* * with the content show in the previous example 4 . 6
  46. 46. FOR OUR FIRST BDD TEST...FOR OUR FIRST BDD TEST... WE ARE GOING TO NEED ...WE ARE GOING TO NEED ... A features directory Inside: a directory named steps. And a file named with extension .feature* * with the content show in the previous example 4 . 6
  47. 47. FOR OUR FIRST BDD TEST...FOR OUR FIRST BDD TEST... WE ARE GOING TO NEED ...WE ARE GOING TO NEED ... A features directory Inside: a directory named steps. And a file named with extension .feature* * with the content show in the previous example 4 . 6
  48. 48. FOR OUR FIRST BDD TEST...FOR OUR FIRST BDD TEST... WE ARE GOING TO NEED ...WE ARE GOING TO NEED ... A features directory Inside: a directory named steps. And a file named with extension .feature* * with the content show in the previous example 4 . 6
  49. 49. mkdir features mkdir features/steps vim features/transfer-between-accounts.feature 4 . 7
  50. 50. FIRST TEST WRITTEN!FIRST TEST WRITTEN! AND IT IS EXECUTABLE!AND IT IS EXECUTABLE! To execute it, just type on the command line: behave 4 . 8
  51. 51. Feature: Transfer between accounts # features/transfer-between Scenario: Add savings # features/t Given I have 10000€ in my current acount # None And I have 300€ in my saving accout # None When I transfer 200€ from current to saving # None Then I should have 9800€ in my current acount # None And I should have 500€ in my saving acount # None Failing scenarios: features/transfer-between-accounts.feature:3 Add savings 0 features passed, 1 failed, 0 skipped 4 . 9
  52. 52. You can implement step definitions for undefined steps with th @given(u'I have 10000€ in my current acount') def step_impl(context): raise NotImplementedError(u'STEP: Given I have 10000€ in m @given(u'I have 300€ in my saving accout') def step_impl(context): raise NotImplementedError(u'STEP: Given I have 300€ in my @when(u'I transfer 200€ from current to saving') def step_impl(context): raise NotImplementedError(u'STEP: When I transfer 200€ fro 4 . 10
  53. 53. IT WORKS!IT WORKS! And It even gives us a scheleton of the functions we need to implement to run the tests ◀ 4 . 11
  54. 54. A SIMPLE TESTA SIMPLE TEST Let's see a first implementation Given thath we have no real code to test for now, use a simulation 4 . 12
  55. 55. GIVEN...GIVEN... #!/usr/bin/env python from behave import * @given("I have 10000€ in my current acount") def step_impl(context): context.current_account = 10000 @given("I have 300€ in my saving accout") def step_impl(context): context.savings_account = 300 4 . 13
  56. 56. WHEN...WHEN... @when("I transfer 200€ from current to saving") def step_impl(context): context.savings_account += 200 context.current_account -= 200 4 . 14
  57. 57. THEN...THEN... @then("I should have 9800€ in my current acount") def step_impl(context): assert context.current_account == 9800 @then("I should have 500€ in my saving acount") def step_impl(context): assert context.savings_account == 500 4 . 15
  58. 58. EXECUTE BEHAVEEXECUTE BEHAVE Feature: Transfer between accounts # features_002/transfer-bet Scenario: Add savings # features_0 Given I have 10000€ in my current acount # features_0 And I have 300€ in my saving accout # features_0 When I transfer 200€ from current to saving # features_0 Then I should have 9800€ in my current acount # features_0 And I should have 500€ in my saving acount # features_0 1 feature passed, 0 failed, 0 skipped 1 scenario passed, 0 failed, 0 skipped 5 steps passed, 0 failed, 0 skipped, 0 undefined Took 0m0.000s 4 . 16
  59. 59. A bit more Theory 4 . 17
  60. 60. PARAMETRIZABLE STEPSPARAMETRIZABLE STEPS We can parse the example text strings and get information for the steps The library is used by default parse defines itself as the opposite of format() parse 4 . 18
  61. 61. Change definition of first step from: To: @given("I have 10000€ in my current acount") def step_impl(context): context.current_account = 10000 @given("I have {amount}€ in my current acount") def step_impl(context, amount): context.current_account = int(amount) 4 . 19
  62. 62. Feature: Transfer between accounts # features_003/transfer-bet Scenario: Add savings # features_0 Given I have 10000€ in my current acount # features_0 And I have 300€ in my saving accout # features_0 When I transfer 200€ from current to saving # features_0 Then I should have 9800€ in my current acount # features_0 And I should have 500€ in my saving acount # features_0 1 feature passed, 0 failed, 0 skipped 1 scenario passed, 0 failed, 0 skipped 5 steps passed, 0 failed, 0 skipped, 0 undefined Took 0m0.001s 4 . 20
  63. 63. WE CAN EVEN FORGETWE CAN EVEN FORGET ABOUT THE INTEGER CASTABOUT THE INTEGER CAST @given("I have {amount:d}€ in my current acount") def step_impl(context, amount): context.current_account = amount 4 . 21
  64. 64. BEHAVE HAVE ALTERNATIVE PARSERSBEHAVE HAVE ALTERNATIVE PARSERS parse is used by default cfparse let us work with cardinality re to use regular expressions 4 . 22
  65. 65. BEHAVE HAVE ALTERNATIVE PARSERSBEHAVE HAVE ALTERNATIVE PARSERS parse is used by default cfparse let us work with cardinality re to use regular expressions 4 . 22
  66. 66. BEHAVE HAVE ALTERNATIVE PARSERSBEHAVE HAVE ALTERNATIVE PARSERS parse is used by default cfparse let us work with cardinality re to use regular expressions 4 . 22
  67. 67. BEHAVE HAVE ALTERNATIVE PARSERSBEHAVE HAVE ALTERNATIVE PARSERS parse is used by default cfparse let us work with cardinality re to use regular expressions 4 . 22
  68. 68. BUT BEFORE...BUT BEFORE... Lets forget all this financial stuff nobody cares for... and use more interesting examples... 4 . 23
  69. 69. POKEMONPOKEMON 4 . 24
  70. 70. TABLE EXAMPLESTABLE EXAMPLES We can add data to the steps in a tabular form Feature: Pokemon search Scenario: Find the weakest Given I have this pokemons |name | attack | defense | |psyduck | 20 | 60 | |torchic | 20 | 60 | |spinda | 10 | 80 | |lillipup | 10 | 50 | When I search for the one with less defense Then I should get lillipup 4 . 25
  71. 71. WE CAN PROCESS THIS TABLEWE CAN PROCESS THIS TABLE IN THE STEP CODEIN THE STEP CODE @given('I have this pokemons') def step_impl(context): for row in context.table: pokemon = Pokemon( row['name'], attack=row['attack'], defense=row['defense'], ) setattr(context, row['name'], pokemon) 4 . 26
  72. 72. WE CAN HAVE SHARED PRECONDITIONSWE CAN HAVE SHARED PRECONDITIONS FOR ALL THE STEPSFOR ALL THE STEPS Feature: Transfer between accounts Background: Given I have this pokemons |name | attack | defense | |psyduck | 20 | 60 | |torchic | 20 | 60 | |spinda | 10 | 80 | |lillipup | 10 | 50 | Scenario: Search for the weakest When I search for the one with less defense Then I should get lillipup 4 . 27
  73. 73. TAGSTAGS Selection of scenarios or features Can select for one or several tags Can execute the ones not having one or more tags 4 . 28
  74. 74. TAGSTAGS Selection of scenarios or features Can select for one or several tags Can execute the ones not having one or more tags 4 . 28
  75. 75. TAGSTAGS Selection of scenarios or features Can select for one or several tags Can execute the ones not having one or more tags 4 . 28
  76. 76. TAGSTAGS Selection of scenarios or features Can select for one or several tags Can execute the ones not having one or more tags 4 . 28
  77. 77. FEATURE WITH TAGSFEATURE WITH TAGS Asuming this feature and sample data Feature: Search pokemons Background: Given I have this pokemons |name | attack | defense | |psyduck | 20 | 60 | |torchic | 20 | 60 | |trapinch | 20 | 60 | |spinda | 10 | 80 | |lillipup | 10 | 50 | 4 . 29
  78. 78. AND THIS STEPSAND THIS STEPS @fight Scenario: Search for the weakest When I search for the one with less defense Then I should get lillipup @fight Scenario: Search for the stronger When I search for the one with more attack Then I should get spinda Scenario: Search for name When I search for the letter t Then I should get torchic And I should get trapinch 4 . 30
  79. 79. EXECUTINGEXECUTING JUST THE FIGHT SCENARIOSJUST THE FIGHT SCENARIOS behave features_006 --tags=fight 4 . 31
  80. 80. EXECUTINGA ALL THE SCENARIOSEXECUTINGA ALL THE SCENARIOS BUT THE FIGHT ONESBUT THE FIGHT ONES behave features_006 --tags=-fight 4 . 32
  81. 81. WORKS IN PROGRESSWORKS IN PROGRESS run with -w flag turns off stdout capture turns off logging capture turns off pretty output only runs scenarios tagged with “@wip” stops at the first error 4 . 33
  82. 82. TO BE HANDLE WITH CARETO BE HANDLE WITH CARE 5 . 1
  83. 83. RECOMENDATIONSRECOMENDATIONS Don't mix features One scenario to test just one case it's code, store it in the repo High level descriptions: Do not use technology terms 5 . 2
  84. 84. DANGERSDANGERS Don't make the system too complex Don't get used to having some tests never passsing Don't start testing the easy ones. You must go for the ones that teaches you the most 5 . 3
  85. 85. DANGERSDANGERS Don't make the system too complex Don't get used to having some tests never passsing Don't start testing the easy ones. You must go for the ones that teaches you the most 5 . 3
  86. 86. DANGERSDANGERS Don't make the system too complex Don't get used to having some tests never passsing Don't start testing the easy ones. You must go for the ones that teaches you the most 5 . 3
  87. 87. DANGERSDANGERS Don't make the system too complex Don't get used to having some tests never passsing Don't start testing the easy ones. You must go for the ones that teaches you the most 5 . 3
  88. 88. RULE NUMBER 1 ON ANALISYS CLUBRULE NUMBER 1 ON ANALISYS CLUB Don't tell me your solution Instead, tell me your problem (Rule number 2 is Everybody lies, if you are interested) 5 . 4
  89. 89. TOOLS AND OPTIONSTOOLS AND OPTIONS Ruby - Cucumber Javascript - Cucumber.js .Net - xBehave Java - JBehave 5 . 5
  90. 90. THANK YOU!THANK YOU! 6

×