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

Fake your test away: How to abuse your test doubles

29a4e399a1da465022ca661f9aa2dc36?s=47 Jenny Shih
November 11, 2021

Fake your test away: How to abuse your test doubles

Presented at RubyConf 2021 by Jenny Shih

https://rubyconf.com/program/sessions#session-1162

29a4e399a1da465022ca661f9aa2dc36?s=128

Jenny Shih

November 11, 2021
Tweet

More Decks by Jenny Shih

Other Decks in Programming

Transcript

  1. @jenny_codes Fake your test away How to abuse your test

    doubles
  2. @jenny_codes

  3. @jenny_codes @ RubyConf Taiwan 2019

  4. @jenny_codes @ RubyConf Taiwan 2019

  5. @jenny_codes @ RubyConf Taiwan 2019

  6. @jenny_codes Let’s talk about Douglas Adams

  7. @jenny_codes Let’s talk about Douglas Adams source: https://www.wallpaper fl are.com/don-t-panic-text-decor-the-hitchhiker-s-guide-to-the-galaxy-wallpaper-pwpgv

  8. @jenny_codes Let’s talk about Douglas Adams Three stages in human

    civilization: • Survival • Inquiry • Sophistication
  9. @jenny_codes Let’s talk about Douglas Adams Three stages in human

    civilization: • Survival: How? • Inquiry: Why? • Sophistication: Where?
  10. @jenny_codes Let’s talk about Douglas Adams Three stages in human

    civilization: • Survival: How can we eat? • Inquiry: Why? • Sophistication: Where?
  11. @jenny_codes Let’s talk about Douglas Adams Three stages in human

    civilization: • Survival: How can we eat? • Inquiry: Why do we eat? • Sophistication: Where?
  12. @jenny_codes Let’s talk about Douglas Adams Three stages in human

    civilization: • Survival: How can we eat? • Inquiry: Why do we eat? • Sophistication: Where shall we have lunch?
  13. @jenny_codes Let’s talk about testing

  14. @jenny_codes Three stages in my relationship with test doubles: Let’s

    talk about testing
  15. @jenny_codes Three stages in my relationship with test doubles •

    Survival: How to use test doubles? Let’s talk about testing
  16. @jenny_codes Three stages in my relationship with test doubles •

    Survival: How to use test doubles? • Inquiry: Why do I test? Let’s talk about testing
  17. @jenny_codes Three stages in my relationship with test doubles •

    Survival: How to use test doubles? • Inquiry: Why do I test? • Sophistication: Where shall I begin to delete my old tests? Let’s talk about testing
  18. @jenny_codes Outline • Unit tests, integration tests, and those in

    between • Integration-test wannabes • Helicopter unit tests • How to not abuse your test doubles?
  19. @jenny_codes Outline • Unit tests, integration tests, and those in

    between • Integration-test wannabes • Helicopter unit tests • How to not abuse your test doubles?
  20. @jenny_codes Test double

  21. @jenny_codes Test double ├─ Stub ├─ Mock └─ Spy

  22. @jenny_codes Subject

  23. @jenny_codes Dependency

  24. Imagine a perfect world

  25. @jenny_codes Testing pyramid Unit tests Integration tests Acceptance tests

  26. @jenny_codes Testing pyramid, reality edition Integration-test wannabes Helicopter unit tests

    Scream tests 🤔 🤔 🤔 🤔
  27. @jenny_codes Testing pyramid, reality edition Helicopter unit tests Scream tests

    🤔 🤔 🤔 🤔 Integration-test wannabes
  28. @jenny_codes Testing pyramid, reality edition Helicopter unit tests Scream tests

    🤔 🤔 🤔 🤔 Integration-test wannabes
  29. @jenny_codes Testing pyramid, reality edition Helicopter unit tests Scream tests

    🤔 🤔 🤔 🤔 Integration-test wannabes
  30. @jenny_codes Outline • Unit tests, integration tests, and those in

    between • Integration-test wannabes • Helicopter unit tests • How to not abuse your test doubles?
  31. @jenny_codes A restaurant that serves French toast

  32. @jenny_codes A restaurant that serves French toast

  33. @jenny_codes A restaurant that serves French toast

  34. @jenny_codes A restaurant that serves French toast

  35. @jenny_codes A restaurant that serves French toast

  36. @jenny_codes The test

  37. @jenny_codes The test

  38. @jenny_codes 🤔 The test

  39. @jenny_codes

  40. @jenny_codes 🔎

  41. @jenny_codes 🔎

  42. @jenny_codes 🔎 🚨

  43. @jenny_codes

  44. @jenny_codes

  45. @jenny_codes

  46. @jenny_codes

  47. @jenny_codes

  48. @jenny_codes

  49. @jenny_codes

  50. @jenny_codes

  51. @jenny_codes ⛔

  52. @jenny_codes

  53. @jenny_codes

  54. @jenny_codes

  55. @jenny_codes Integration-test wannabes (n.) Tests with randomly inserted test doubles

    because the real objects are too awkward to deal with.
  56. @jenny_codes ❌ Random doubles == Random test failures Integration-test wannabes

  57. @jenny_codes One month later…

  58. @jenny_codes One month later… FAILED

  59. @jenny_codes Therapeutic Refactoring by Katrina Owen, Cascadia Ruby Conf 2012

  60. @jenny_codes

  61. @jenny_codes when I don’t have to modify 100 random test

    failures for it
  62. @jenny_codes ❌ Random doubles == Random test failures ❌ Decreased

    productivity Integration-test wannabes
  63. Test doubles are contracts

  64. @jenny_codes Outline • Unit tests, integration tests, and those in

    between • Integration-test wannabes • Helicopter unit tests • How to not abuse your test doubles?
  65. @jenny_codes Restaurant Service: Cheese Panini

  66. @jenny_codes

  67. @jenny_codes

  68. @jenny_codes

  69. @jenny_codes

  70. @jenny_codes Chef Waiter Restaurant Service The dependency graph Floor 🛸

    🌝 🐢 Cupboard Fridge Bread Cheese class-level dependency instance-level dependency
  71. @jenny_codes The dependency graph 🙈 🙈 Chef Waiter Restaurant Service

    Cupboard Fridge Bread Cheese class-level dependency instance-level dependency test double 🙈 🙈 🙈
  72. @jenny_codes The dependency graph 🙈 🙈 Chef Waiter Restaurant Service

    class-level dependency instance-level dependency test double 🙈 🙈 🙈 🙈 🙈
  73. @jenny_codes

  74. @jenny_codes

  75. @jenny_codes

  76. @jenny_codes

  77. @jenny_codes

  78. @jenny_codes

  79. @jenny_codes

  80. @jenny_codes

  81. @jenny_codes Helicopter unit tests (n.) Tests that try to control

    every implementation detail in the subject.
  82. @jenny_codes ❌ Fake empire The helicopter unit tests

  83. @jenny_codes https://media.giphy.com/media/IguL9zRYV20X1QeKuV/giphy.gif Production Your CI The helicopter unit tests

  84. @jenny_codes ❌ Fake empire ❌ Brittle tests The helicopter unit

    tests
  85. @jenny_codes ❌ Fake empire ❌ Brittle tests The helicopter unit

    tests GUARANTEED
  86. @jenny_codes ❌ Fake empire ❌ Brittle tests The helicopter unit

    tests x N
  87. @jenny_codes Outline • Unit tests, integration tests, and those in

    between • Integration-test wannabes • Helicopter unit tests • How to not abuse your test doubles?
  88. @jenny_codes hard-to-use code == hard-to-write test easy-to-use code == easy-to-write

    test
  89. @jenny_codes Tests are the first consumer of your API

  90. @jenny_codes https://twitter.com/dan_abramov/status/1456265490754510848/photo/1 Write an unit test that can’t catch errors

    Write an integration test that has holes it
  91. @jenny_codes • 🎁 • 🎁 • 🎁 How to not

    abuse your test doubles?
  92. @jenny_codes • Use the Principle of Least Knowledge • 🎁

    • 🎁 How to not abuse your test doubles?
  93. @jenny_codes Principle of Least Knowledge Don’t talk to strangers

  94. @jenny_codes Principle of Least Knowledge

  95. @jenny_codes Principle of Least Knowledge Life Universe Everything Answer

  96. @jenny_codes Principle of Least Knowledge Life Universe Everything Answer

  97. @jenny_codes Principle of Least Knowledge Life Universe Answer Everything

  98. @jenny_codes Principle of Least Knowledge Answer Everything Universe Life

  99. @jenny_codes Principle of Least Knowledge Don’t talk to strangers Low

    coupling
  100. @jenny_codes Principle of Least Knowledge Don’t talk to strangers Low

    coupling
  101. @jenny_codes Principle of Least Knowledge Don’t talk to strangers Low

    coupling
  102. @jenny_codes

  103. @jenny_codes

  104. @jenny_codes

  105. @jenny_codes

  106. @jenny_codes

  107. @jenny_codes

  108. @jenny_codes Use Principle of Least Knowledge: Result

  109. @jenny_codes Use Principle of Least Knowledge: Result

  110. @jenny_codes • Use the Principle of Least Knowledge • 🎁

    • 🎁 How to not abuse your test doubles?
  111. @jenny_codes How to not abuse your test doubles? • Use

    the Principle of Least Knowledge • Separate decisions and delegations. • 🎁
  112. @jenny_codes Decision • Logic • Condition • Calculation • Dependency

    • Relationships Delegation
  113. @jenny_codes

  114. @jenny_codes = delegation = decision

  115. @jenny_codes 1. Get resources 2. Prepare ingredients 3. Make dish

    4. Serve dish
  116. @jenny_codes 1. Get resources

  117. @jenny_codes 1. Get resources 2. Prepare ingredients 3. Make dish

    4. Serve dish
  118. @jenny_codes 1. Get resources 2. Prepare ingredients 3. Make dish

    4. Serve dish => waiter => waiter => chef
  119. @jenny_codes Separate decision and delegation: Result

  120. @jenny_codes Separate decision and delegation: Result

  121. @jenny_codes

  122. @jenny_codes

  123. @jenny_codes

  124. @jenny_codes Separate decision and delegation: Result Arrange Act Assert

  125. @jenny_codes Separate decision and delegation: Result

  126. @jenny_codes Decision • Logic • Condition • Calculation • Unit

    test • Dependency • Relationships Delegation
  127. @jenny_codes Decision • Logic • Condition • Calculation • Unit

    test • Dependency • Relationships • Integration test Delegation
  128. @jenny_codes Testing pyramid with decision and delegation Unit tests Integration

    tests Acceptance tests Decisions Delegation
  129. @jenny_codes How to not abuse your test doubles? • Use

    the Principle of Least Knowledge • Separate decisions and delegations • 🎁
  130. @jenny_codes • Use the Principle of Least Knowledge • Separate

    decision and delegation • Make the dependencies really obvious How to not abuse your test doubles?
  131. @jenny_codes All dependencies are equal, but some are more equal

    than others.
  132. @jenny_codes All dependencies are equal, but some are more equal

    than others. the side-e ff ect free the rest
  133. @jenny_codes All dependencies are equal, but some are more equal

    than others. the side-e ff ect free the rest 🤤
  134. @jenny_codes All dependencies are equal, but some are more equal

    than others. the side-e ff ect free the rest 🤤 ⚠
  135. @jenny_codes the side-e ff ect free 🤤 All dependencies are

    equal, but some are more equal than others. the rest ⚠ ⚠ ⚠ ⚠ ⚠ ⚠⚠⚠ ⚠
  136. @jenny_codes Revisit serve_french_toast

  137. @jenny_codes Chef Waiter Restaurant Service Floor 🛸 🌝 🐢 class-level

    dependency instance-level dependency Revisit serve_french_toast
  138. @jenny_codes Revisit serve_french_toast Chef Waiter Restaurant Service Floor 🛸 🌝

    🐢 class-level dependency instance-level dependency
  139. @jenny_codes Revisit serve_french_toast Chef Waiter Restaurant Service Floor 🛸 🌝

    🐢 class-level dependency instance-level dependency
  140. @jenny_codes Revisit serve_french_toast Chef Waiter Restaurant Service Floor 🛸 🌝

    🐢 class-level dependency instance-level dependency
  141. @jenny_codes Revisit serve_french_toast Chef Waiter Restaurant Service Floor 🛸 🌝

    🐢 class-level dependency instance-level dependency How to make those dependencies obvious?
  142. @jenny_codes Revisit serve_french_toast Chef Waiter Restaurant Service Floor 🛸 🌝

    🐢 class-level dependency instance-level dependency
  143. @jenny_codes Chef Waiter Restaurant Service Floor 🛸 🌝 🐢

  144. @jenny_codes Chef Waiter Restaurant Service Floor 🛸 🌝 🐢

  145. @jenny_codes Chef Waiter Restaurant Service Floor 🛸 🌝 🔻 🐢

    Restaurant Repo
  146. @jenny_codes Chef Waiter Restaurant Service Floor 🛸 🌝 🔻 🐢

    Restaurant Repo
  147. @jenny_codes

  148. @jenny_codes ⚠ ⚠ ⚠

  149. @jenny_codes

  150. @jenny_codes

  151. @jenny_codes Make dependencies obvious: Result

  152. @jenny_codes Make dependencies obvious: Result

  153. @jenny_codes Make dependencies obvious: Result

  154. @jenny_codes • Use the Principle of Least Knowledge • Separate

    decision and delegation • Make the dependencies really obvious How to not abuse your test doubles?
  155. @jenny_codes Design your system so there’s no room to abuse

    your test doubles
  156. One last thing

  157. @jenny_codes Talks that inspire me • Gary Bernhardt: Boundaries •

    Justin Searls: Please don’t mock me • Justin Searls: How to stop hating your test • Katrina Owen: Therapeutic refactoring • All the talks by Sandi Metz really
  158. @jenny_codes Books that inspire me • The Art of Unit

    Testing by Roy Osherove • Domain Modeling Made Functional by Scott Wlaschin • The Hitchhiker’s Guide to the Galaxy by Douglas Adams
  159. @jenny_codes Talk to me! or just @jenny_codes