A standard software engineering practice in Java and other languages is to use a unit testing framework like JUnit and develop tests in a separate file that exercise the public API of the class being tested.
While this is a fine practice, I tend to embed a lot of tests directly in classes. This way, the tests are executed every time the class is run, whether in development or production.
For example, using this toy representation of a bank account:
The standard approach is to develop a test class in another file and invoke it using a test harness from Maven or an IDE:
My personal preference is to embed the tests directly in the class and invoke them from a static
initialization block:
There are a couple of differences to notice here. Instead of having public
methods on an instance of a test suite, we have private static
functions. This uses some helper code for invoking the tests from the static
initializer.
One might object that this is costly because the tests execute every time the code is initialized. I find that this cost is negligible and well worth the expense as I am guaranteed to find problems in cases where I might not run the test framework. This has the added bonus that I am not tempted to make some implementation method more visible just to appease the testing framework. I can keep functions and methods private
and still testable.
Another advantage is that I consider the unit test cases to be documentation of the expected behavior. Such documentation should be in the same file, in my opinion.
While external test harnesses are still needed for integration tests or tests that will take a long time to run, I get a lot of value out of the reduced friction of having the unit tests embedded directly in the class I am developing.