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.

Double Loop: TDD & BDD Done Right!

1,850 views

Published on

Do you TDD or BDD? Why not both? Come learn the "Double Loop" workflow and discover how you can use both Behavior Driven Development and Test Driven Development to write well designed, tested and documented code. Double Loop works for lone engineers, small teams or entire product departments. I'll cover the steps you'll take in the workflow as each role as well as tools for executing Double Loop

Published in: Software

Double Loop: TDD & BDD Done Right!

  1. 1. Double Loop TDD & BDD Done Right! @jessicamauerhan | #ATO2016
  2. 2. @jessicamauerhan Senior Software Engineer TDD/BDD Expert jessicamauerhan@gmail.com jmauerhan.wordpress.com
  3. 3. @jessicamauerhan | #ATO2016 What is Test Driven Development? Test Driven Development is a process in which you first write a failing unit test, execute that test, write just enough code to make the test pass, then refactor that code for improvements.
  4. 4. @jessicamauerhan | #ATO2016 Benefits of Test Driven Development ● Guides you towards creating a well-abstracted and highly modular system. ● Makes the software easier to change, maintain and understand. ● Promotes using design patterns, refactoring, and helps prevent scope creep. ● Complete test coverage ● Preventing and identifying regressions and mistakes with automated tests ● Executable documentation. Primary Secondary
  5. 5. @jessicamauerhan | #ATO2016 What is Behavior Driven Development? Behaviour-driven development is an “outside-in” methodology. It starts at the outside by identifying business outcomes, and then drills down into the feature set that will achieve those outcomes. Each feature is captured as a “story”, which defines the scope of the feature along with its acceptance criteria. Dan North, “What’s in a Story” http://dannorth.net/whats-in-a-story It’s the idea that you start by writing human-readable sentences that describe a feature of your application and how it should work, and only then implement this behavior in software. Behat Documentation http://docs.behat.org/en/v2.5
  6. 6. @jessicamauerhan | #ATO2016 Why Practice BDD? ● Well Designed Code ● Automated Testing ● Implementation ● UI Testing BDD Is Not About... ● Communication ● Collaboration ● Documentation ● Preventing Regressions BDD Is About...
  7. 7. @jessicamauerhan | #ATO2016 Why Practice Behavior Driven Development? “You can turn an idea for a requirement into implemented, tested, production-ready code simply and effectively, as long as the requirement is specific enough that everyone knows what’s going on.” Dan North, “What’s in a Story” http://dannorth.net/whats-in-a-story
  8. 8. @jessicamauerhan | #ATO2016 Accuracy Unit Tests describe accuracy of code and prescribe maintainable code Suitability Behavior Tests describe suitability of software's features for the end user
  9. 9. @jessicamauerhan | #ATO2016 Testing Pyramid Maintenance Coverage Fragility Duration Cost Number of Tests Unit Tests Behavior Tests System Tests (performance) GUI Tests Unit Behavior System GUI Manual QA Testing Ice Cream Cone
  10. 10. @jessicamauerhan | #ATO2016 The Vicious Cycle of the Testing Ice Cream Cone Unit Behavior System GUI Manual QA Non Testable Code More Expensive Tests Developers Don't Run Tests More Bugs Developers Don't Write Unit Tests
  11. 11. Add Behavior Test Add Unit Test Run Unit Test Add/Edit Some Code Refactor Run All Unit Tests Run All Behavior Tests Pass* Fail Fail Pass Run Behavior Test Pass* Fail Fail Pass Revert Changes @jessicamauerhan | #ATO2016 Double Loop: TDD & BDD Done Right! Feature Done? NoYes * A test that passes the first time before code has been written means the test is inaccurate or poorly written, not added to the test suite, or the code/feature already exists.
  12. 12. Add Behavior Test
  13. 13. @jessicamauerhan | #ATO2016 Parts of a Behavior Test ● Feature: Gherkin ● Test Code ● BDD Framework / Test Runner
  14. 14. @jessicamauerhan | #ATO2016 Gherkin ● Business Readable, Domain Specific Language ● Living Documentation / User Manual ● User Story with Narrative ● Contains at least one Scenario: Acceptance Criteria
  15. 15. @jessicamauerhan | #ATO2016 ● Narrative ○ As a [role] I want [feature] So that [benefit / business reason] ○ Use “5 Whys” to determine narrative As an Account Holder I want to withdraw cash from an ATM So that I can get money when the bank is closed Scenario: Account has sufficient funds Given the account has a balance And the card is valid And the machine contains at least the amount of my balance When I request an amount less than or equal to my balance Then the ATM should dispense that amount And the amount should be subtracted from my account balance And the card should be returned Scenario: Account has insufficient funds Given the account has a balance And the card is valid And the machine contains at least the amount of my balance When I request an amount greater than my balance Then the ATM should not dispense any money And the ATM should say there are insufficient funds And my account balance should not change And the card should be returned ● Feature: Short, Descriptive, Action ● Acceptance Criteria: Scenarios ○ Given: Exact Context ○ When: Action/Event ○ Then: Outcomes ○ And/But: More of the same... ● Feature: Account Holder Withdraws Cash
  16. 16. @jessicamauerhan | #ATO2016 As a user viewing a broadcast page before the broadcast starts I want to see a countdown timer So that I can know how long until the broadcast actually starts Scenario: View Countdown before Broadcast Given I view the “Future Broadcast” broadcast Then I should see "Future Broadcast" on the page And I should see "Future Broadcast Author" on the page And I should see "This broadcast begins at 6:00 pm EST" on the page And I should see a countdown timer Feature: View Countdown before Broadcast Process ● Author describes Feature with implementation specific example ● Developer adds fixture data Issues ● Test only works before 6pm ● What is the intent? ● Confusion for business users
  17. 17. @jessicamauerhan | #ATO2016 As a user viewing a broadcast page before the broadcast starts I want to see a countdown timer So that I can know how long until the broadcast actually starts Scenario: View Countdown before Broadcast Given there is a broadcast scheduled for the future When I view that broadcast’s page Then I should see the broadcast title And I should see the broadcast author’s name And I should see "This broadcast begins at" followed by the start time in EST And I should see a countdown timer Feature: View Countdown before Broadcast Changes ● Given now explains exact context ● Test is no longer time-dependent ● Intent - not implementation Why? ● Overall understanding ● Communication value ● Help identify poorly written code
  18. 18. @jessicamauerhan | #ATO2016 Feature: Customer Views Product and Services Catalog As a customer I want to view the product catalog So that I can browse products and services Scenario: Customer views Product Catalog Given I view the catalog When I select a state from the list of states Then I should see the list of products for sale Scenario: Display Local Services in Product Catalog Given the company has a regional office in a state When I view the catalog And I select that state from the list of states Then I should see the list of services offered echo '<h1>Products</h1>'; foreach ($products AS $product) { echo '<p>' . $product->getName() . '</p>'; } echo '<h1>Services</h1>'; foreach ($services AS $service) { echo '<p>' . $service->getName() . '</p>'; } Scenario: Don’t Display Local Services in Product Catalog For States With No Regional Office Given the company does not have a regional office in a state When I view the catalog And I select that state from the list of states Then I should not see a list of services offered
  19. 19. @jessicamauerhan | #ATO2016 Feature: Customer Views Product and Services Catalog As a customer I want to view the product catalog So that I can browse products and services Scenario: Customer views Product Catalog Given I view the catalog When I select a state from the list of states Then I should see the list of products for sale Scenario: Display Local Services in Product Catalog Given the company has a regional office in a state When I view the catalog And I select that state from the list of states Then I should see the list of services offered Scenario: Don’t Display Local Services in Product Catalog For States With No Regional Office Given the company does not have a regional office in a state When I view the catalog And I select that state from the list of states Then I should not see a list of services offered echo '<h1>Products</h1>'; foreach ($products AS $product) { echo '<p>' . $product->getName() . '</p>'; } if(count($services) > 0) { echo '<h1>Services</h1>'; foreach ($services AS $service) { echo '<p>' . $service->getName() . '</p>'; } }
  20. 20. @jessicamauerhan | #ATO2016 Writing Great Features ● Exact Context ● Independent Scenarios & Features ● Intention, not Implementation ● Defined Narrative ● All Paths Explored Feature “Smells” ● Time Dependency ● Interdependency ● Multi-Scenario Scenarios ● Missing Scenarios ● Overuse of Variables ● Examples of Behavior (Implementation, not Intention)
  21. 21. @jessicamauerhan | #ATO2016 Parts of a Behavior Test ● Feature: Gherkin ● Test Code ● BDD Framework / Test Runner
  22. 22. @jessicamauerhan | #ATO2016 BDD Frameworks / Test Runners ● Java - JBehave, Cucumber and more ● Ruby - Cucumber ● PHP - Behat ● JavaScript - cucumber.js, jasmine ● ...
  23. 23. @jessicamauerhan | #ATO2016 Scenario: Customer views Product Catalog Given I view the catalog When I select a state from the list of states Then I should see the list of products for sale Behat Code/** * @Given I view the catalog */ public function iViewTheCatalog() { $this->visit('catalog'); } /** * @When I select a state from the list of states */ public function iSelectAStateFromTheListOfStates() { $this->selectOption('states', rand(1, 52)); } /** * @Then I should see the list of products for sale */ public function iShouldSeeTheListOfProductsForSale() { $productsDiv = $this->getSession() ->getPage() ->find('css', '#products'); Assertion::notNull($productsDiv); }
  24. 24. Add Behavior Test Run Behavior Test Pass* @jessicamauerhan | #ATO2016 Double Loop: TDD & BDD Done Right! * A test that passes the first time before code has been written means the test is inaccurate or poorly written, not added to the test suite, or the code/feature already exists.
  25. 25. @jessicamauerhan | #ATO2016 Parts of a Behavior Test ● Feature: Gerkhin ● Test Code ● BDD Framework / Test Runner
  26. 26. Add Behavior Test Add Unit Test Run Behavior Test Pass* Fail Double Loop: TDD & BDD Done Right! * A test that passes the first time before code has been written means the test is inaccurate or poorly written, not added to the test suite, or the code/feature already exists. @jessicamauerhan | #ATO2016
  27. 27. @jessicamauerhan | #ATO2016 Writing Unit Tests What is a unit? ● Unit: As small as possible ● Design and Describe behavior ○ Setup scenario for behavior ○ Cause behavior to occur ○ Assert result is as expected ● Verbose and Descriptive Names
  28. 28. Add Behavior Test Add Unit Test Run Unit Test Run Behavior Test Pass* Fail Double Loop: TDD & BDD Done Right! * A test that passes the first time before code has been written means the test is inaccurate or poorly written, not added to the test suite, or the code/feature already exists. @jessicamauerhan | #ATO2016
  29. 29. @jessicamauerhan | #ATO2016 Executing Unit Tests ● Ensures test fails when code is broken ● Ensures test is added to suite ● Tells you exactly what to do next Always execute before writing production code
  30. 30. Add Behavior Test Add Unit Test Run Unit Test Add/Edit Some Code Fail Run Behavior Test Pass* Fail Double Loop: TDD & BDD Done Right! * A test that passes the first time before code has been written means the test is inaccurate or poorly written, not added to the test suite, or the code/feature already exists. @jessicamauerhan | #ATO2016
  31. 31. @jessicamauerhan | #ATO2016 Writing Code Just Enough ● Add just enough code to pass the test ● Avoid over abstracting or adding untested logic
  32. 32. @jessicamauerhan | #ATO2016 Three Types of Unit Tests ● Correctness ● Contract ● Collaboration
  33. 33. New Class For User Registration Class: Registration Service Unit Tests Registration Service Correctness Third Party Service API (Mailer) Integrated Test MailChimp API Forgot Password Weekly Newsletter Direct Message Exciting Event Reminder! @jessicamauerhan | #ATO2016 TDD: Integration Testing with Contract & Collaboration Tests
  34. 34. New Class For User Registration Class: Registration Service Third Party Service API (Mailer) Collaborator: Mailer Mailer Contract (Interface / Abstract) Mailer Interface Test Double Persistence Layer Persistence Layer (Interface / Abstract) Persistence Layer Test Double Fully Unit Tested & Implemented Class: Registration Service Unit Tests Registration Service Correctness Collaboration Tests Collaboration Tests @jessicamauerhan | #ATO2016 TDD: Integration Testing with Contract & Collaboration Tests
  35. 35. Third Party Service API (Mailer) Mailer Implementation Class: Mailchimp Adapter New Class For User Registration Class: Registration Service Collaborator: Mailer Mailer Contract (Interface / Abstract) Mailer Interface Test Double Persistence Layer Persistence Layer (Interface / Abstract) Persistence Layer Test Double Fully Unit Tested & Implemented Class: Registration Service Unit Tests Registration Service Correctness Collaboration Tests Collaboration Tests Third Party Tool: MailChimp API (This is a Contract) Mailchimp API Double Fully Unit Tested & Implemented Class: Mailchimp Adapter Correctness Unit Tests Contract Tests Collaboration Tests @jessicamauerhan | #ATO2016 TDD: Integration Testing with Contract & Collaboration Tests
  36. 36. Mailer Implementation Class: SendBlue Adapter New Class For User Registration Class: Registration Service Third Party Service API (Mailer) Collaborator: Mailer Mailer Contract (Interface / Abstract) Mailer Interface Test Double Persistence Layer Persistence Layer (Interface / Abstract) Persistence Layer Test Double Fully Unit Tested & Implemented Class: Registration Service Unit Tests Registration Service Correctness Collaboration Tests Collaboration Tests Third Party Tool: SendBlue (This is a Contract) Third Party Tool: SendBlue (This is a Contract) SendBlue API Double Fully Unit Tested & Implemented Class: SendBlue Adapter Class: SendBlue Adapter Correctness Unit Tests Contract Tests Collaboration Tests @jessicamauerhan | #ATO2016 TDD: Integration Testing with Contract & Collaboration Tests Forgot Password Weekly Newsletter Direct Message Exciting Event Reminder!
  37. 37. Maintenance Coverage Fragility Duration Cost Number of Tests Isolated Unit Tests Correctness, Contract & Collaboration Integration Testing Multiple Components Integrated Tested for Correctness & Communication Behavior Tests Fully Integrated User Experience System Tests load balance, performance, security GUI Tests
  38. 38. Add Behavior Test Add Unit Test Run Unit Test Add/Edit Some Code Fail Run Behavior Test Pass* Fail @jessicamauerhan | #ATO2016 Double Loop: TDD & BDD Done Right! * A test that passes the first time before code has been written means the test is inaccurate or poorly written, not added to the test suite, or the code/feature already exists.
  39. 39. @jessicamauerhan | #ATO2016 Failing Test or Test Suite? Revert! ● If the test fails, revert your work ● Commit small changes, often!
  40. 40. Add Behavior Test Add Unit Test Run Unit Test Add/Edit Some Code Refactor Run All Unit Tests Pass* Fail Fail Pass Run Behavior Test Pass* Fail Revert Changes @jessicamauerhan | #ATO2016 Double Loop: TDD & BDD Done Right! Feature Done? NoYes * A test that passes the first time before code has been written means the test is inaccurate or poorly written, not added to the test suite, or the code/feature already exists.
  41. 41. @jessicamauerhan | #ATO2016 Refactoring The process of restructuring code without changing its behavior
  42. 42. @jessicamauerhan | #ATO2016 Refactoring ● Improving non-functional aspects ● Removing duplication ● Renaming ● Simplifying Unit Tests Always Passing! ● Changes that would break a unit test ● New functionality that is not tested New Unit Tests Fail, Then Pass Adding Functionality
  43. 43. Add Behavior Test Add Unit Test Run Unit Test Add/Edit Some Code Refactor Run All Unit Tests Run All Behavior Tests Pass* Fail Fail Pass Run Behavior Test Pass* Fail Fail Pass Revert Changes Double Loop: TDD & BDD Done Right! Feature Done? NoYes * A test that passes the first time before code has been written means the test is inaccurate or poorly written, not added to the test suite, or the code/feature already exists. @jessicamauerhan | #ATO2016
  44. 44. @jessicamauerhan | #ATO2016 Thank You! Double Loop: TDD & BDD Done Right! Feedback & Questions? Welcome & Encouraged! @jessicamauerhan jessicamauerhan@gmail.com jmauerhan.wordpress.com

×