The phrase "unit testing" evokes a wide variety of opinions within the
developer community. At this point, most individuals understand the
concept through direct experience or community osmosis. In fact, the TDD
(test-driven development) model is initiated through the development of
a failed test that satisfies a new feature. Once completed, a developer
performs the minimum amount of coding required to pass the test. This
continues through an iterative cycle until the code meets an acceptable
standard. Over the past 10 years, dozens of unit testing frameworks have
been built by the developer community to satisfy the need for unit
testing. Frameworks exist for compiled languages (e.g. Java, C++, .NET),
(e.g. SQL, PL/SQL, MySQL).
Unit testing has a variety of well documented benefits. Unit tests find problems earlier in the process, which saves QA testing efforts. Unit tests allow programmers to have a high level of confidence when refactoring code because broken tests identify missing logic. Unit tests simplify the integration process of multiple components. If each component was built and verified by unit tests, validating the integration of those pieces consumes less time. Unit tests provide a quasi living document of functionality. This is invaluable when there is a lack of documentation. Unit testing can also replace a formal design document because the unit test specifies the form, function, and desired result.
The previous statements paint a positive, albeit wide, picture of unit testing; unfortunately, every concept has its limitations and concerns. There are a few difficult questions with unclear answers. Below are a series of observations:
- As with the original code, building a unit test relies upon a developer's coding ability.
- Unit testing does not eliminate other testing requirements; it complements them. This extends the amount of time to complete a feature.
- Unit tests can only "show the presence or absence of particular errors; they cannot prove a complete absence of errors."
- The initial addition of unit tests to a per-existing project or code base is time consuming.
- Where is the point of diminishing returns? In a non-TDD world, when does a developer stop building tests for a feature? More tests do not equal less bugs.