Aslak and I were brought on to a project with the task of refactoring a fairly large legacy codebase. Approximately 30 thousands lines of code, written over a 2 year timeframe, by 10-20 programmers. No pair programming involved, no TDD, and no formal reviews. Clover was reporting about about 60% coverage in the form of Junit tests (approximately 1100 tests).
The goal: Disentangle the GUI portion of this codebase (AWT stuff) from the domain layer. Eventually rewrite the GUI as a remote client, and expose the domain layer as a clean and reusable public API.
Problematic Unit Tests
- First of all, the damn things taking about 10-15 minutes to execute.
- As a result, nobody running the suite on a regular basis except cruise control
- Suite only passes in forked JVM mode, because of excessive use of statics requires pristine environment
- ...running the suite in-process reveals they almost all clobber each other in non-deterministic ways
- Not only that, the suite can't easily be run from IDE, because of hundreds of dependencies on test files to be in the right place in the test file system before running suite. Not just ordinary resources, but specially arranged XML and HSQL db files also
The bottom line: the majority of these tests weren't actually unit tests at all. Sure, they all extended JUnit TestCase, but most of them did some sort of file I/O, many included calls to Thread.sleep(), and during their execution there would be about 20-30 AWT windows popping up and flashing stuff in my face.