These lessons seem like the kind of thing I ought to blog about, but since they occur to me spontaneously during work when I'm trying to get other things done, I'm not sure I want to take the time to do more than just note them down. If you're interested in talking about any particular one of them, feel free to post a comment and I'd love to have a discussion.
- Classes should implement the minimal interface necessary to get them to do what you want them to do. Functions that operate primarily on one class but aren't part of that class's minimal interface should be outside that class. This makes it possible to stub out the class for testing those functions.
- In Python, when a function returns a set of items in an indeterminate order, I should use set() instead of a list, because it simplifies unit testing.
- For a class that represents something read from disk, the reading and interpreting of that thing should be outside the class, so that the class can be initialized from non-disk in unit tests.
- Refactoring unit tests while writing them is easier than it looks. This belongs in a theme of "refactoring: it's easier than it looks and it leads to code clarity."
- Nice trick for sharing code between similar unit tests: have a function with a lot of optional args, each optional arg specifying a variant to test.
- Nice way to separate concerns when unit testing an algorithm whose purpose is to perform some action and generate output for the user: have one function that performs the action and yields the output in data structures, and another function that accepts the data structures and pretty-prints them for the user. These two functions can be unit tested separately, so that the unit test for the algorithm doesn't have to account for pretty-printing of the output.