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

Fearlessly Improving Legacy Code - PhillyXP

Fearlessly Improving Legacy Code - PhillyXP

Fearlessly Improving Legacy Code (or: How I Learned to Stop Worrying and Love Dreadful Code)

Complicated, convoluted, obfuscated, messy code without any unit tests; some call it "spaghetti code" or a "big ball of mud." There are a lot of names and euphemisms for what we call legacy code. This code often invites developers to create more of it because it can be time-consuming and unsafe to change. We tend to make the most straightforward, smallest change possible, and the code continues on its death spiral until it can no longer be patched. It can be scary to have to work in legacy code.

In this talk, I'll share my nine rules for characterization testing and show them in practice by working through a legacy code kata I have created. If you learn these rules for approaching this type of code, you'll see improving legacy code does not have to be scary. You may even grow to enjoy it as I did!

Anthony Sciamanna

November 15, 2022
Tweet

More Decks by Anthony Sciamanna

Other Decks in Programming

Transcript

  1. @asciamanna
    anthonysciamanna.com @asciamanna
    anthonysciamanna.com
    Fearlessly Improving
    Legacy Code
    or: How I Learned to Stop Worrying
    and Love Dreadful Code
    Anthony Sciamanna
    Senior Consultant - Industrial Logic

    View full-size slide

  2. @asciamanna
    anthonysciamanna.com
    Legacy code can be scary!
    Photo by Andrea Piacquadio

    View full-size slide

  3. @asciamanna
    anthonysciamanna.com
    How do you change your perspective?
    https://www.industriallogic.com/training/elearning/
    Industrial Logic eLearning Album - Legacy Code
    Working Effectively with Legacy Code - Michael Feathers
    ● Nine rules for characterization testing
    ● Inspired by the WELC book (Michael
    Feathers) and Industrial Logic Legacy
    Code eLearning

    View full-size slide

  4. @asciamanna
    anthonysciamanna.com
    Characterization tests
    Source: Working Effectively with Legacy Code - Michael Feathers
    In computer programming, a characterization test (also known as Golden Master Testing) is a means
    to describe (characterize) the actual behavior of an existing piece of software, and therefore protect
    existing behavior of legacy code against unintended changes via automated testing. This term was
    coined by Michael Feathers. [Source: Wikipedia]
    Characterization Tests Golden Master Tests Pinning Tests
    Pin-Down Tests Scaffolding Tests Approval Tests

    View full-size slide

  5. @asciamanna
    anthonysciamanna.com
    Legacy code death spiral
    Make the most
    straightforward, smallest
    change that feels the safest
    in the short term (no
    improvements) Design degrades
    further making future
    changes harder
    Need to modify
    convoluted, untested
    legacy code
    Creates more
    duplication and
    conditional complexity
    Why?
    ● “I don’t have time to [learn how
    to] improve the code.”
    ● “I fear I’ll break the functionality
    because it isn’t clear.”

    View full-size slide

  6. @asciamanna
    anthonysciamanna.com
    Conditional logic and code duplication are the Yin and
    Yang of unmaintainable code.
    - Bryan Helmkamp - CEO, Code Climate
    “ ”

    View full-size slide

  7. @asciamanna
    anthonysciamanna.com
    Why does this happen?
    ● Organizational pressure
    ● Taylorism (developers are order takers / typists)
    ● Managing teams by output (velocity)
    ● Short term speed is the only success measure
    ● We don’t know how / No time to learn
    ● Lack of agile engineering practices

    View full-size slide

  8. @asciamanna
    anthonysciamanna.com
    REWRITE!
    ● Same team(s)
    ● Same (or additional) organizational pressures
    ● Same organizational view on software
    development (Taylorism)
    ● Never learned / practiced how to
    incrementally improve the code
    …Your rewrite is DOOMED!

    View full-size slide

  9. @asciamanna
    anthonysciamanna.com
    Law of Holes
    Source: Wikipedia - https://en.wikipedia.org/wiki/Law_of_holes
    The first law of holes, or the law of holes, is an adage
    which states: "if you find yourself in a hole, stop
    digging." It is used as a metaphor, warning that when
    in an untenable position, it is best to stop making the
    situation worse

    View full-size slide

  10. @asciamanna
    anthonysciamanna.com
    Team Working Agreements
    All new code comes with microtests
    All existing code gets tested when it needs to be changed

    View full-size slide

  11. @asciamanna
    anthonysciamanna.com
    Music profile kata

    View full-size slide

  12. @asciamanna
    anthonysciamanna.com
    Rule #1 - Clear the area
    ● Once the change area is identified
    ○ Reformat the file (automatically)
    ○ Use team-shared formatting and linting rules
    ○ Remove obvious noise in the code without
    needing to think about it

    View full-size slide

  13. @asciamanna
    anthonysciamanna.com
    Claude Shannon - “Father of Information Theory”
    "Almost every problem that you come across is
    befuddled with all kinds of extraneous data of
    one sort or another; and if you can bring this
    problem down into the main issues, you can see
    more clearly what you're trying to do."
    Source Business Insider
    From his lecture “Creative Thinking” at Bell Labs - March 20, 1952
    Wikipedia: Claude Shannon

    View full-size slide

  14. @asciamanna
    anthonysciamanna.com
    Rule #2 - Use power tools
    Code
    Editors
    IDEs
    Provides automation tools,
    automated refactorings, test
    runners, code coverage tools

    View full-size slide

  15. @asciamanna
    anthonysciamanna.com
    Arlo Belshee’s Core Six Refactorings
    You should never have to do these things:
    ● Format your code
    ● Type basic language stuff / get things precisely right
    ● Look up what refactorings you can use and their
    keystrokes
    Source: https://arlobelshee.com/the-core-6-refactorings/

    View full-size slide

  16. @asciamanna
    anthonysciamanna.com
    Rule #3 - Call it in a test harness
    ● Can you create the object you want to test?
    ● Can you call the method with null arguments?
    ● Call method under test with simple arguments to start
    (then elaborate)
    xUnit framework,
    unit testing
    framework, or
    Approval Tests
    https://github.com/approvals
    https://approvaltests.com/

    View full-size slide

  17. @asciamanna
    anthonysciamanna.com
    Rule #4 - Use tests to get to testability
    ● Probe existing behavior with tests
    ● DO NOT spend time trying to figure
    out complicated, obfuscated logic
    Try this…
    Not that…

    View full-size slide

  18. @asciamanna
    anthonysciamanna.com
    Rule #5 - Let assertion failures expose the behavior
    ● Assert null to discover results
    ● Write assertions for actual results
    Agile in a Flash - Tim Ottinger & Jeff Langr
    Source: Working Effectively with Legacy Code - Michael Feathers

    View full-size slide

  19. @asciamanna
    anthonysciamanna.com
    Rule #6 - Examine inputs and outputs
    ● Are the outputs for a single pass covered in assertions?
    ● “Outputs” could be void calls on dependencies
    ● How many possible input combinations are there? (Helps
    to give you an idea of the number of tests you’ll need)

    View full-size slide

  20. @asciamanna
    anthonysciamanna.com
    Rule #7 - Use code coverage to drive input variation
    ● Vary inputs to cover more of the legacy code
    ● Track progress via code coverage
    ● Look for hidden branches - regex matches, LINQ
    chaining (C#), streams (Java)
    ● Tools: Console Writing & Debugger

    View full-size slide

  21. @asciamanna
    anthonysciamanna.com
    Rule #8 - Use automated refactoring to create seams
    ● Seams allow for breaking dependencies and
    getting to testability
    ● Exploit seams by replacing objects with test
    doubles (object seams)
    ● Addresses the Legacy Code Dilemma

    View full-size slide

  22. @asciamanna
    anthonysciamanna.com
    Legacy Code Dilemma
    “When we change code we should have tests in place. To put tests in
    place we often have to change code.”
    -Michael Feathers
    Source: Working Effectively with Legacy Code - Michael Feathers

    View full-size slide

  23. @asciamanna
    anthonysciamanna.com
    Seams
    A seam is a place where you can alter behavior
    in your program without editing it
    Every seam has an enabling point, a place
    where you can make the decision to use one
    behavior or another
    Source: Working Effectively with Legacy Code - Michael Feathers
    We introduce test doubles to exploit object seams

    View full-size slide

  24. @asciamanna
    anthonysciamanna.com
    Rule #9 - Don’t fix bugs
    ● You do want to fix them, just not now
    ● Characterize the bug’s behavior instead

    View full-size slide

  25. @asciamanna
    anthonysciamanna.com
    Next - Refactor and Introduce Microtests
    ● Once legacy code is characterized (including bug behavior)...
    ○ Refactor production code
    ○ Cover in microtests
    ○ Delete or refactor characterization tests
    ○ Fix identified bugs

    View full-size slide

  26. @asciamanna
    anthonysciamanna.com
    Microtests
    Microtests are micro in size, run in milliseconds, and test a
    micro-behavior. They are fast and cheap, and you can run the
    tests thousands of times without false negatives.
    Because they are so small they are very easy to scan and
    understand

    View full-size slide

  27. @asciamanna
    anthonysciamanna.com
    Microtests Don’t
    ● Access a database
    ● Access the network
    ● Access the filesystem
    ● Depend on other tests
    ● Require a complex environment to run in
    ● Require a deployed app to test against

    View full-size slide

  28. @asciamanna
    anthonysciamanna.com @asciamanna
    anthonysciamanna.com
    Contact Info:
    Anthony Sciamanna - [email protected]
    Twitter: @asciamanna
    Web: anthonysciamanna.com
    This talk: https://bit.ly/phillyxp-legacy-code
    Thank you!

    View full-size slide