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.

Navigating the xDD Alphabet Soup

770 views

Published on

TDD, BDD, ATDD are all methodologies that enable incremental design that is suitable for Agile environments. It seems that every day a new xDD methodology is born with the promise to be better than what came before. Should you use behaviour-driven tests or plain old unit tests? Which methodology is better? And how exactly would it benefit the development life cycle?

In this session, Dror will help to sort out the various methodologies – explaining where they came from, the tools they use, and discussing how and when to use each one. Here we will once and for all answer the question as to whether or not there’s one “DD” to rule them all.

Published in: Technology
  • Be the first to comment

Navigating the xDD Alphabet Soup

  1. 1. http://blog.drorhelper.com
  2. 2. A history lesson Methodologies Books! Books! Books! Tools overview
  3. 3. little a few flaws lot many more flaws feature works customer's requirements
  4. 4. 1991 1994 1997 2000 2002 Taligent framework NUnit 2.0Kent Beck writes first version of SUnit test framework* Kent Beck & Erich Gamma create JUnit During a flight to OOPSLA Michael Features ports JUnit to C++ (CppUnit)
  5. 5. Test Suite Fixture Test Case Test Case Test Case Test Case Test Case Fixture Test Case Test Case Fixture Test Case Test Case Test Case public class BeforeAndAfter { @Before public void setUp() { } @After public void tearDown() { } @Test public void test1() { } @Test public void test2() { } }
  6. 6. method specific functionality, clear pass/fail runs in isolation
  7. 7. feedback stupid regression without fear documentation
  8. 8. Red Green Refactor
  9. 9. is not
  10. 10. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); }
  11. 11. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); } public class ArabicToRoman { }
  12. 12. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } public class ArabicToRoman { }
  13. 13. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } public class ArabicToRoman { public String convert(int num) { return null; } }
  14. 14. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } public class ArabicToRoman { public String convert(int num) { return null; } }
  15. 15. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } public class ArabicToRoman { public String convert(int num) { return “I”; } }
  16. 16. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } public class ArabicToRoman { public String convert(int num) { return “I”; } }
  17. 17. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } @Test public void Pass2_ReturnII() { cut = new ArabicToRoman(); String result = cut.convert(2); assertEquals("II", result); } public class ArabicToRoman { public String convert(int num) { return “I”; } }
  18. 18. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } @Test public void Pass2_ReturnII() { cut = new ArabicToRoman(); String result = cut.convert(2); assertEquals("II", result); } public class ArabicToRoman { public String convert(int num) { return “I”; } }
  19. 19. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } @Test public void Pass2_ReturnII() { cut = new ArabicToRoman(); String result = cut.convert(2); assertEquals("II", result); } public class ArabicToRoman { public String convert(int num) { if(i == 2) return "II"; return "I"; } }
  20. 20. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } @Test public void Pass2_ReturnII() { cut = new ArabicToRoman(); String result = cut.convert(2); assertEquals("II", result); } public class ArabicToRoman { public String convert(int num) { if(i == 2) return "II"; return "I"; } }
  21. 21. @Test public void Pass1_ReturnI() { cut = new ArabicToRoman(); String result = cut.convert(1); assertEquals("I", result); } @Test public void Pass2_ReturnII() { cut = new ArabicToRoman(); String result = cut.convert(2); assertEquals("II", result); } public class ArabicToRoman { public String convert(int num) { result = new StringBuilder(); for(int i = 0 ; i < num ; i++) { result.append("I"); } return result.toString(); } }
  22. 22. S.Else Server Call CommClient Phone RingMessage OnCallRequested AmazingUIAmazing UI S Calling U Accept Call ConnectToServer ConnectMessage
  23. 23. Server Comm Client UITestFake Comm
  24. 24. “ ” implementing what you think the users want
  25. 25. 1996 2002 2002 2003 Automated tests are part of Extreme Programming. Ward Cunningham publishes Fit Bob Martin combines Fit with Wikis tocreate Fitnesse Kent Beck briefly mentions ATDD in “TDD: By Example” but dismisses it as impractical
  26. 26. user story development team implementation phase.
  27. 27. Unit tests Acceptance tests Fast Slow No side effects Side effects Simple to run Dependent on environment Test single “unit of work” Test single scenario/feature Written by developers Written by customers Verify that code works Overall system works as required Test must pass before check-in Test may only pass when feature is done Fake other units Fake other systems
  28. 28. numerator Denominator quotient? 10 2 5.0 12.6 3 4.2 100 4 33 org/FitNesse.FullReferenceGuide.UserGuide.WritingAcceptanceTests.FixtureCode public class Division { private double numerator, denominator; public void setNumerator(double numerator) { this.numerator = numerator; } public void setDenominator(double denominator) { this.denominator = denominator; } public double quotient() { return numerator/denominator; } }
  29. 29. Red Green Refactor Red Green Refactor Red Green RefactorRed Green Refactor Red Green Refactor Red Green Refactor Red Green Refactor
  30. 30. Discuss DistillDevelop Demo ed.com/wp-content/uploads/2011/04/atddexample.pdf Story item Red Green Refactor TDD
  31. 31. “ ” Specifications are supposed to be general Examples only highlight a few points http://martinfowler.com/bliki/SpecificationByExample.html
  32. 32. /drawings/d/1cbfKq-KazcbMVCnRfih6zMSDBdtf90KviV7l2oxGyWM/edit?hl=en Business goal/desired effect Scope Key Examples Specification with Examples Executable Specification Living Documentation Derive the scope from goals Specify collaboratively Refine the specification Validate frequently Automate literally
  33. 33. Sensors PLC ModelClient Business logic Raw data Converted data command
  34. 34. less of a wax-on, wax-off process of gradual mastery than a series of blind alleys… presentTDD in a way that gets straight to the good stuff and avoids all the pitfalls.
  35. 35. public class CustomerLookupTest extendsTestCase { testFindsCustomerById() { } testFailsForDuplicateCustomers() { } }
  36. 36. × Test123 × CustomerTest × PerchaseOrderTestNew × MoveBatteryVanilla  CalculateTax_InvalidYear_LogErrorToFile  OrdersShouldBeCreated  OrdersWithNoProductsShouldFail
  37. 37. “ ” comprehensively describe the behaviour of your system “Behaviour” is a more useful word than “test”
  38. 38. Steps Scenarios Story In Order to… As a… I want to… Scenario 1 Given When Then Scenario 2 Given When Then
  39. 39. public class TraderSteps{ private TradingService service; private Stock stock; @Given("a stock and a threshold of $threshold") public void aStock(double threshold) { stock = service.newStock("STK", threshold); } @When("the stock is traded at price $price") public void theStockIsTraded(double price){ stock.tradeAt(price); } @Then("the alert status is $status") public void theAlertStatusIs($status){ assertThat(stock.getStatus().Name(), equalTo(status)); } } Scenario: A trader is alerted of status Given a stock and a threshold of 15.0 When stock is traded at 5.0 Then the alert status should be off
  40. 40. Feature: Addition In order to avoid silly mistakes As a math idiot I want to be told the sum of two numbers Scenario: Add two numbers Given I have entered 50 into the calculator And I have entered 70 into the calculator When I press add Then the result should be 120 on the screen From: https://cukes.info/
  41. 41. describe Stack do it "should return a blank instance" do Stack.new.should == {} end it "element is added to the stack on top of the stack" do stack = Stack.new stack.push 'a value' stack.pop.should == 'a value' end end Stack should return a blank instance element is added to the stack on top of the stack
  42. 42. [Test] public void OutOfStorageWhileCreatingFileAndExactFilesToMakeRoom() { var fakeSystemInfo = A.Fake<ISystemInfo>(); A.CallTo(() => fakeSystemInfo.GetFreeDiskSpaceInBytes()).Returns(0); var logfiles = new[] { new LogFile { Name = "file-1.log", Size = 50000 }, new LogFile { Name = "file-2.log", Size = 50000 } }; var fakeLogFolder = A.Fake<ISharedStorageFolder>(); A.CallTo(() => fakeLogFolder.GetFiles()).Returns(logfiles); var logFileWriter = new LogFileWriter(fakeSystemInfo, fakeLogFolder); logFileWriter.Write("some message"); A.CallTo(() => fakeLogFolder.DeleteFile("file-1.log")).MustHaveHappened(); A.CallTo(() => fakeLogFolder.DeleteFile("file-2.log")).MustHaveHappened(); }
  43. 43. SCENARIO("First roll is strike") { GIVEN("Bowled strike on first turn") { Game game; game.Roll(10); WHEN("Next roll is spare then roll five") { game.Roll(3); game.Roll(7); game.Roll(5); RollSeveral(game, 15, 0); THEN("Total score is 40") { REQUIRE(game.Score() == 40); } } WHEN("Next two rolls are strike then gutter balls") { game.Roll(10); game.Roll(10); RollSeveral(game, 16, 0); THEN("Total score is 60") { REQUIRE(game.Score() == 60); } } } }
  44. 44. TDD Classic London ATDD SbE BDD Stories Specification
  45. 45. Choose 2
  46. 46. “ ”http://lizkeogh.com/2011/03/04/step-away-from-the-tools/
  47. 47. http://geek-and-poke.com/geekandpoke/2013/6/6/dont-ask-your-boss
  48. 48. “ ”http://blog.mattwynne.net/2012/11/20/tdd-vs-bdd/
  49. 49. They're just both useful to have in your back pocket as you go around trying to write decent software to solve useful problems. But I bet that's what Kent Beck would say if you asked him whatTDD was all about. Dan North, DefiningTDD, https://groups.google.com/forum/#!msg/behaviordrivendevelopment/OQnb3APpUJk/RklRiyEKde4J
  50. 50. Thank you drorh@codevalue.net http://blog.drorhelper.com

×