- Test until bored. Ask "is there any chance this is wrong?" If so, write a test for it. If not, you're done.
- If the test and the system-under-test would look the same, skip the test, because of DRY.
- If the code reads like a spec, test by inspection: read it and confirm that it says the right stuff.
- If a function has a side-effect-free query, followed by an action based on the results of the query, split them and test separately.
- I'm not very good at figuring out how to design code well, but I can tell when code is hard to test. making code easy to test usually works out well for me. If I have to mock A to test B, that's harder than factoring out B and testing it directly. So, I refactor.
These are all different ways of saying pretty much the same thing.