• ALWAYS implement a tested version of the demonstration from the component specification.
  • ALWAYS provide a meaningful message in assert and fail calls.
  • ALWAYS document your test code as well as you document your component code.
  • Break up your tests into discrete TestCase classes. If one TestCase becomes unmanageable, don't hesitate to break it into two or more classes.
  • Break up your tests within those classes into the smallest functions possible; this way, it is clear which areas of the component are failing. You can then use the number of tests passing and failing as a completion metric, as well.
  • Reduce code duplication and increase robustness with setUp() and tearDown().
  • Test every public function for as much valid and invalid input as time allows.
  • Test expected component processes: loading, processing data, and saving data, for instance.
  • Don't forget to clean up your environment! Unit tests should leave the system in the same state they found it in; there should be no persistent changes. This is checked during development review.
  • Test classes are normal classes in every respect, except that they have special significance to the testing framework. These classes can inherit from a class intermediate between themselves and the final test. They may contain methods other than test methods. They may have state.
  • Because they are in the same package or namespace as the component classes they test, the unit tests can access package-private and protected classes and their members.
  • Interfaces cannot be tested directly, but methods that accept interface arguments can be presented with alternative implementations. This technique has great potential for verifying that the component does the expected things with and to its interface-typed fields and method arguments, and that it reacts correctly to exceptions thrown by methods invoked on such arguments.