Test Your Legacy Code

6b767d8a4c9910e007c122d81eb4de73?s=47 Noel Rappin
November 07, 2011

Test Your Legacy Code

Presented at RubyMidwest, November 2011

6b767d8a4c9910e007c122d81eb4de73?s=128

Noel Rappin

November 07, 2011
Tweet

Transcript

  1. Test Your Legacy Code Noel Rappin @noelrap Monday, November 7,

    11
  2. You are handed a “rescue” project Monday, November 7, 11

  3. Oh. My. God. The last person to work on this

    was an idiot Monday, November 7, 11
  4. Now what? Monday, November 7, 11

  5. Shake your fists at the heavens for one minute. Photo

    by Sha Sha Chu http://www.flickr.com/photos/shashachu/88654315/ Monday, November 7, 11
  6. Get back to work. Monday, November 7, 11

  7. What is a legacy application? Monday, November 7, 11

  8. Code without tests Monday, November 7, 11

  9. Code based on lost requirements Monday, November 7, 11

  10. You don’t know what “correct” means Monday, November 7, 11

  11. What’s your goal? Monday, November 7, 11

  12. Respect working code. Do no harm. Monday, November 7, 11

  13. Deliver features Monday, November 7, 11

  14. At a sustainable pace Monday, November 7, 11

  15. Improve code quality Monday, November 7, 11

  16. The Boy Scout Rule Monday, November 7, 11

  17. Our rescue project needs to change Monday, November 7, 11

  18. Goofus and Gallant Monday, November 7, 11

  19. “First, let’s write tests and cover the whole app” Monday,

    November 7, 11
  20. “That change is easy, I’ll just drop that in” Monday,

    November 7, 11
  21. They are both Goofus Monday, November 7, 11

  22. Why not cover the whole app in tests? Monday, November

    7, 11
  23. “It’s a small world, but I wouldn’t want to paint

    it” Monday, November 7, 11
  24. It’s not a quick win Monday, November 7, 11

  25. You can introduce bugs Monday, November 7, 11

  26. Why not just drop something in? Monday, November 7, 11

  27. It sets a bad precedent Monday, November 7, 11

  28. It doesn’t make anything better Monday, November 7, 11

  29. What’s a Gallant Software Craftsman to do? Monday, November 7,

    11
  30. The basic TDD process... Monday, November 7, 11

  31. ...applied to new changes only Monday, November 7, 11

  32. Red. Green. Refactor. Monday, November 7, 11

  33. Over time, coverage and quality grow organically Monday, November 7,

    11
  34. Okay, it’s not that easy Monday, November 7, 11

  35. Why not? Monday, November 7, 11

  36. You don’t know what to test Monday, November 7, 11

  37. It’s hard to isolate objects under test Monday, November 7,

    11
  38. A friendly reminder: git is your friend Monday, November 7,

    11
  39. Cucumber Photo by karenandbradmerson http://www.flickr.com/photos/karenandbrademerson/492770419 Monday, November 7, 11

  40. Cucumber is independent of the code Monday, November 7, 11

  41. Cucumber can cover a lot of the app quickly Monday,

    November 7, 11
  42. But... Monday, November 7, 11

  43. Cucumber is slow Photo by matley0 http://www.flickr.com/photos/matley0/2973398121/ Monday, November 7,

    11
  44. And it’s not great at isolating where a problem is

    Monday, November 7, 11
  45. Test-Driven Exploration Monday, November 7, 11

  46. It’s like TDD... with cheating Monday, November 7, 11

  47. Red. Make it green. Refactor. Monday, November 7, 11

  48. The code is source of truth Monday, November 7, 11

  49. Mock Testing Monday, November 7, 11

  50. Mocks are fast and allow unit testing Monday, November 7,

    11
  51. But they can be hard to set up Monday, November

    7, 11
  52. Isolation Monday, November 7, 11

  53. Only touch existing methods to call your new methods Monday,

    November 7, 11
  54. def crazy_insane_method return clean_new_method if new_condition # all the old

    ugly stuff end Monday, November 7, 11
  55. Seams Photo by boogah http://www.flickr.com/photos/boogah/4541496/ Monday, November 7, 11

  56. Default method arguments Monday, November 7, 11

  57. def crazy_insane_method(arg, arg, new_arg = nil) # crazy insane stuff

    # now with new stuff end Monday, November 7, 11
  58. Changing behavior without touching code Monday, November 7, 11

  59. Monday, November 7, 11

  60. class TestPurchase < Purchase def bang # no-op end end

    user.purchase << TestPurchase.new Monday, November 7, 11
  61. class Purchase def bang # no-op end end Monday, November

    7, 11
  62. Singleton classes Monday, November 7, 11

  63. x = Purchase.new x.def bang # no-op end Monday, November

    7, 11
  64. Duck Typing Photo by Andyofne http://www.flickr.com/photos/andyofne/3757051334/ Monday, November 7, 11

  65. class TestPurchase def bang # no-op end end user.purchase <<

    TestPurchase.new Monday, November 7, 11
  66. Use a pebble Photo by Slideshow Bruce http://www.flickr.com/photos/springfieldhomer/39079430/ Monday, November

    7, 11
  67. class Pebble def initialize(name) @name = name end def method_missing(method_name,

    *args) p "#{method_name}(#{args.join(", ")}) from #{caller_method}" self end end Monday, November 7, 11
  68. def caller_method(depth = 1) parse_caller(caller(depth+1).first).last end def parse_caller(at) if /^(.+?):(\d+)(?::in

    `(.*)')?/ =~ at file = Regexp.last_match[1] line = Regexp.last_match[2].to_i method = Regexp.last_match[3] [file, line, method] end Monday, November 7, 11
  69. What about bad tests? Monday, November 7, 11

  70. Make sure the suite runs Monday, November 7, 11

  71. Tests are also code Monday, November 7, 11

  72. The 5-minute rule Monday, November 7, 11

  73. When to refactor Monday, November 7, 11

  74. Simple refactors can be done at any time... Monday, November

    7, 11
  75. ...as long as the tests are green Monday, November 7,

    11
  76. Especially if you can’t test without refactoring Monday, November 7,

    11
  77. More complex refactors should be tied to actual new requests

    Monday, November 7, 11
  78. And in conclusion... Monday, November 7, 11

  79. Respect working code Monday, November 7, 11

  80. Test at as high a level as you can Monday,

    November 7, 11
  81. Leave things better than you found them Monday, November 7,

    11
  82. Isolate code under test Monday, November 7, 11

  83. Consider the cost of change against the cost of no

    change Monday, November 7, 11
  84. railsrx.com @noelrap Rails Test Prescriptions Rate: http://bit.ly/nrmwtest Monday, November 7,

    11