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

Thought Driven Development

12d6ff93ca25d366161efccadd81bbb2?s=47 Alexey Buzdin
September 26, 2015

Thought Driven Development

Some thought on the way we Develop and Test our products

12d6ff93ca25d366161efccadd81bbb2?s=128

Alexey Buzdin

September 26, 2015
Tweet

More Decks by Alexey Buzdin

Other Decks in Programming

Transcript

  1. THOUGHT DRIVEN DEVELOPMENT by @AlexeyBuzdin

  2. @AlexeyBuzdin Developer / Trainer at

  3. DOES THIS CODE WORK? def trySend (Mail mail) { try

    { mailService.send mail } catch (ServerTimeOutException e) { /* TODO: Handle error here */ } }
  4. NO IDEA TO BE HONEST…

  5. HOW TO MAKE SURE?

  6. RUN THE THING!

  7. ZE CODE AGAIN def trySend (Mail mail) { try {

    mailService.send mail } catch (ServerTimeOutException e) { /* TODO: Handle error here */ } }
  8. ZE CODE AGAIN def trySend (Mail mail) { try {

    mailService.send mail } catch (ServerTimeOutException e) { /* TODO: Handle error here */ } } HOW MANY PATHS?
  9. 3+ HOW MANY PATHS?

  10. 3+ HOW MANY PATHS? HAPPY PATH SERVER TIMEOUT ?

  11. 3+ HOW MANY PATHS? HAPPY PATH SERVER TIMEOUT ?

  12. 3+ HOW MANY PATHS? HAPPY PATH SERVER TIMEOUT ?

  13. ZE CODE AGAIN def trySend (Mail mail) { try {

    mailService.send mail } catch (ServerTimeOutException e) { /* TODO: Handle error here */ } }
  14. 3+ HOW MANY PATHS? HAPPY PATH SERVER TIMEOUT NULL POINTER

  15. RUN THE THING 1!

  16. RUN THE THING 1! RUN THE THING 2!

  17. RUN THE THING 1! RUN THE THING 2! RUN THE

    THING 3!
  18. None
  19. WHO HAS DONE THIS?

  20. DEBUGGING CODE TO UNDERSTAND WHERE IS THE FAILURE

  21. IN 99% THIS IS WRONG!

  22. TESTS

  23. TESTS ARE MADE TO MAKE YOU FEEL SECURE!

  24. LIKE A LOVELY HUG ♥

  25. YOU NEED TO ADD SOMETHING TO THIS CODE

  26. public byte[] scaleImage(InputStream is, int maxWidth, int maxHeight, ImageType type)

    throws IOException { if (is == null) throw new IOException(String.format("Input stream is unavailable for image type %s", type.getMime())); BufferedImage source = ImageIO.read(is); int width = source.getWidth(); int height = source.getHeight(); int scaledWidth = width; int scaledHeight = height; if (width > maxWidth) { scaledWidth = maxWidth; scaledHeight = (int) Math.ceil((scaledWidth * height * 1.0) / width); } if (scaledHeight > maxHeight) { scaledHeight = maxHeight; scaledWidth = (int) Math.ceil((scaledHeight * width * 1.0) / height); } source = (width < maxWidth || height < maxHeight) ? subImage(source, width, height, maxWidth, maxHeight) : scale(source, width, height, scaledWidth, scaledHeight); ByteArrayOutputStream stream = new ByteArrayOutputStream(); ImageIO.write(source, type.getMime(), stream); return stream.toByteArray(); }
  27. NO TESTS…

  28. NO TESTS… DO YOU FEEL SECURE?

  29. TESTS ARE AWESOME!

  30. THUS…

  31. LETS SELL THEM!

  32. LETS SELL THEM! EVANGELIZE

  33. (TDD) TEST-DRIVEN DEVELOPMENT

  34. CLASSIC TDD 1. ADD A TEST 2. RUN ALL TESTS

    3. WRITE SOME CODE 4. RUN TESTS 5. REFACTOR CODE 6. REPEAT
  35. CONFIDENCE MEANS STRICT RULES?

  36. I WANT TO BE A BADASS!

  37. AWESOME AND CONFIDENT

  38. None
  39. EATING ELEPHANT PIECE BY PIECE

  40. EATING ELEPHANT PIECE BY PIECE AND KEEPING HIM ALIVE IN

    THE PROCESS!
  41. ATOMIC COMMITS?

  42. SINGLE COMMIT OR SINGLE TEST DOES NOT BRING ANY VALUE

  43. SINGLE TEST DOES NOT BRING ANY VALUE MERGE WITH MASTER

    DOES SINGLE COMMIT OR
  44. SINGLE TEST DOES NOT BRING ANY VALUE TESTED USER STORY

    DOES SINGLE COMMIT OR
  45. SO WHY EXTRA EFFORT?

  46. SO WHY EXTRA EFFORT? BECAUSE IT’S COOL!

  47. Test-Driven Development

  48. Kent Beck stated that TDD: - encourages simple designs -

    inspires confidence Test-Driven Development
  49. TOOLS ARE MEANT TO HELP

  50. Kent Beck stated that TDD: - encourages simple designs -

    inspires confidence TDD acts as a self-documenting code Test-Driven Development
  51. Kent Beck stated that TDD: - encourages simple designs -

    inspires confidence TDD acts as a self-documenting code Test-Driven Development but on which level?
  52. Kent Beck stated that TDD: - encourages simple designs -

    inspires confidence TDD acts as a self-documenting code Test-Driven Development but on which level? LETS THINK!
  53. THOUGHT DRIVEN DEVELOPMENT

  54. AS A USER I WANT TO POST A TWEET

  55. ARE YOU CONFIDENT ABOUT THIS?

  56. NO? THEN TEST IT!

  57. BUT WHAT IF CONNECTION FAILS?

  58. UNSURE? THEN TEST IT!

  59. FEATURES ARE NOT LIKELY TO BE REMOVED

  60. FEATURES ARE LIKELY TO EVOLVE

  61. FEATURES ARE LIKELY TO EXPAND

  62. def join(List<String> tokens, String separator) HOW MANY TEST WOULD YOU

    WRITE?
  63. def join(List<String> tokens, String separator) {
 def sb = new

    StringBuilder()
 boolean first = true
 for (String item : tokens)
 {
 if (first) first = false
 else sb.append separator
 sb.append item
 }
 return sb.toString
 } HOW MANY TEST WOULD YOU WRITE?
  64. def join(List<String> tokens, String separator) {
 def sb = new

    StringBuilder()
 boolean first = true
 for (String item : tokens)
 {
 if (first) first = false
 else sb.append separator
 sb.append item
 }
 return sb.toString
 } HOW MANY TEST WOULD MAKE YOU CONFIDENT?
  65. @Test def joinsStrings() { def actual = util.join(Arrays.asList("hello", "world"), ";")

    assertThat(actual, equalTo "hello;world") } IS ONE ENOUGH?
  66. TECHNICAL BOILERPLATE WILL LIKELY TO BE CHANGED

  67. TECHNICAL BOILERPLATE AND IT’S TESTS WILL LIKELY TO DIE

  68. GOOD TEST IS LIKELY TO BE #BROKEN

  69. TEST BEHAVIOR, NOT CODE!

  70. BUT TEST AS LOW AS IT MAKES SENSE

  71. IDENTIFY INDEPENDENT MODULES/LAYERS

  72. MAKE END-TO-END TESTS FOR CORE FUNCTIONALITY

  73. ALWAYS TEST PUBLIC API EXTENSIVELY!

  74. SOMETIMES LET CLIENTS TEST YOUR APP!

  75. Scenario: New Customer is retrieved by ID Given request body

    from file json/newCustomer.json When the client performs POST request on /customers Then status code is 201 And header Location end with customers/(.+) And assign variable "{(location)}" to header "Location" value When the client performs GET request on {(location)} Then status code is 200 And response body contains properties from file json/newCustomer.json Acceptance Test-Driven Development (ATDD)
  76. ALWAYS TEST POINTS OF INTEGRATIONS FOR TRICKY CASES!

  77. ALWAYS TEST INPUT

  78. ALWAYS EXTENSIVELY TEST CODE, THAT MAKES YOU MONEY!

  79. CODE COVERAGE

  80. CODE COVERAGE IS YOUR SIDEKICK

  81. CODE COVERAGE IS YOUR SIDEKICK NOT A COMPETITOR

  82. TAKE AWAYS

  83. TAKE AWAYS LET TESTS GUIDE YOUR HAND

  84. TAKE AWAYS LET TESTS GUIDE YOUR HAND TEST FOR EACH

    FAILURE ACCOUTERED
  85. TAKE AWAYS LET TESTS GUIDE YOUR HAND TEST FOR EACH

    FAILURE ACCOUTERED TEST MEANINGFUL CODE
  86. TAKE AWAYS LET TESTS GUIDE YOUR HAND TEST FOR EACH

    FAILURE ACCOUTERED TEST MEANINGFUL CODE TEST-DOCUMENT PUBLIC API
  87. BUT SOMETIMES HEAR OUT YOUR GUTS!

  88. Q&A @AlexeyBuzdin #bycraft