February 14, 2009
(see also TddEfficiency)

Reasons to do unit testing, from my own paper on XP (slightly tweaked):

Each unit test is a sentry assigned to monitor the piece of functionality it tests. At the time it's written, it may seem too small a thing to worry about. However, the amount of code in even a small project can grow very quickly. Without an automatic way to check every important detail in the code, soon the code will not be exercised regularly. Growing a collection of unit tests from day one becomes an extremely powerful tool later on in the project.

Having a consistent test suite eliminates fragile code [see UnitTestsAndCoupling]. In the later stages of a project, programmers are usually hesitant to revisit previously written code because it's either buggy and/or messy or because it's solid -- which pretty much runs the gamut. The reason is the same regardless of the quality of the code -- fear of making a mistake and introducing new problems or breaking things that have been working.

The unit tests remove this fear. Programmers can make bold changes and see the cost of the change immediately by re-running the test suite.

Unit testing also promotes good design. It's easy to create highly coupled code without unit tests because for every one production object often times there's only one other production object using it, at least when the code is first written. Unit tests ensure that everything tested will have 2 clients from inception -- the production code that uses it and the unit test that tests it. Requiring code to be responsive to multiple clients forces less coupling of objects which promotes long term flexibility. This flexibility is a crucial contributor to resilience.

As an added bonus, unit tests make for great usage documentation. Separate example code does not need to be written. If unit tests are written thoroughly, example code exists for free. This can greatly reduce if not eliminate the amount of internal documentation required.

[from Collective Ownership section:]

XP aims to avoid hang-ups caused by individual ownership by focusing ownership of the team on the whole. Take pride in the whole, not in the individual contributions to the whole. The project itself must succeed as a whole to be effective, and that should be the goal of any development effort.

Collective ownership allows anyone on the team at any time to work with any piece of code. If a pair working with object A needs object B to change, that pair can go immediately make the change in object B to accommodate the needs of object A.

The practice of quickly dipping into a related piece of code to make a quick change can be dangerous, because quick changes can often times create side-effect bugs. In an XP project, however, every piece of code is developed test-first, ensuring each piece of functionality is unit tested. If the quick edit fixed one thing but broke several others, the test suite will be run shortly after the edit was made and report the errors immediately to the programmer who just made the edit.

In a large codebase, many times testing out the new production being built requires running the entire application and sometimes this involves a lot of unrelated navigation and setup. All of this extra execution and navigation time can be costly, even for just manually testing one case.

If there are several use cases, then frequently it's too expensive to sit there and manually re-verify the previously completed use cases while working on the next one, even though there's a decent chance additional cases may start to collide with previous cases introducing bugs at a time where discovery would render them very cheap to fix.

Running from a unit test harness can bypass all of the unrelated execution and navigation, and automate setting up necessary dependencies plus immediate regression tests of all of the previous test cases just coded. Over the course of just a few hours, the process can be much more efficient than coding without unit tests.

tags: ComputersAndTechnology