Our tests should:
- Assure us that the code is behaving correctly.
- Allow us to refactor with confidence.
- Help us write more maintainable code.
- Choose the part of the code you want to test (a class, a group of classes, the full end to end stack). For functional tests, try and pick a group that is at the same "level", or that achieve an isolated unit of work that makes sense as a standalone function.
- Draw a mental box around the classes that will be in the test. Everything inside that box should be able to be completely refactored (methods renamed, classes renamed, code moved around) without breaking this test. Only mock or stub or test calls to things at the edges of the box.