In this chapter, you saw how to handle the hairy problem of working with the legacy code. We defined the legacy code as any code that does not contain tests. It is an unfortunate fact of life that we have to deal with such code. Fortunately there are a number of techniques available that allow us to safely work with such code. The interactive shell as well as the extremely powerful debugger are a huge help in understanding typical spaghetti code.
The dynamic nature of Python also makes it easy to break dependencies. We can use default value parameters to maintain compatibility with existing code while refactoring to a better design. Powerful patching features as well as the ability to dynamically alter existing instance variables and local methods allow us to write characterization tests that would normally have been much more difficult.
Now that you have seen many ways to write tests, let's look at ways to keep everything maintainable. We will do this in the next chapter.