Test Driven Development
Author: Scott Collins, Synaction Consulting Group
You may or may not have heard of the term Test Driven Development. It is a term used to describe a development
practice in which unit tests that are used to prove that software works as designed are written before the actual code is developed.
This practice is more than just an industry buzz word, it can mean the difference between a good product and an exceptional
quality product.
Before understanding the importance of Test Driven Development, it is important to understand what unit tests really are.
What Is Unit Testing?
A unit test is a piece of code written to prove that code within a product functions as designed. Unit tests are
written by a developer that has knowledge of how the code works. Unit tests are often referred to as "White Box"
tests because the unit tests can test the internals of the code. Integration testing, in contrast, tests how the modules
work together to form the final product. Since integration tests have no knowledge of the internals of the code, it is often
referred to as "Black Box" testing.
Unit tests are designed to test a number of factors within the code. They not only test that the code produces the expected results,
but they also test that methods can receive a proper range of inputs and that the methods handle errors gracefully. It is the combination
of all these factors that make unit testing a wise investment.
Test Driven Development
Test Driven Development (TDD) uses unit tests as the foundation for building code. Unit tests can be written at any point during the
development process. For example, a developer can write unit tests after the product has been completed. However the main philosophy
behind TDD is to write the unit tests first, before any code has been written.
The process is simple. When the developer first receives the requirements for a new piece of functionality, they stub out the interfaces
for the code that will be used to implement the functionality. Before writing any implementation, the developer then writes unit tests
to test various conditions that must be met by th final code. These unit tests answer fundamental questions about the quality of the code, such as:
- "What are the valid range of values that the code can accept?"
- "What is considered a successful execution of the code?"
- "What should be done if an error occurs during processing or if an invalid value is passed to the method?"
Initially, when these unit tests are run, they will all fail because no implementation exists yet. Once the developer is sure that they have written
enough unit tests to ensure quality code, then they move on to writing the implementation. As the functionality is coded, the developer
can run the unit tests to see which tests pass and which ones fail. Once all unit tests complete successfully, the developer knows that all
the required functionality has been implemented, and they can move on to the next requirement.
Test Driven Development Leads To Better Quality
So how does Test Driven Development lead to better quality? The use of test driven development has a number of benefits to both the developer
and to the company producing the product.
More Robust Software
Writing unit tests before writing the code forces the developer to design the code in a way that will be testable. This means that code for
validation and execution will be in discrete units rather than in the user interface. The code will also be more modular. Since writing unit tests to exercise
a small piece of functionality embedded in a large complex routine is difficult, the developer is forced to architect the system in a way that facilitates
testing. These factors lead the developer to create smaller, more modular units of code that are more easily maintained in the future. Better
maintainability leads to less cost in the long run.
It also allows the developer to be confident when making changes in the future. For example, assume that Developer A is writing a complex portion
of code for version 1.0 of the application. Later that year, version 1.5 of the application is being developed, and Developer B has been assigned
the task of including new functionality in the module written by Developer A. Developer B requires changes to the existing code in order to
accomplish the task. Developer B finishes his changes and declares the new functionality a success. Later, when the code has reached quality assurance,
defects are logged against the functionality that was coded by Developer A and released in version 1.0. What seemed like a minor change to the existing
code base resulted in breaking existing functionality. Everyone is in a panic because the new version needs to ship and developers end up working
overtime in order to track down the bug. The release schedule is delayed and the cost of writing the application increases.
This scenario can be completely avoided with proper unit testing. Lets look at the same scenario using Test Driven Development. Developer A
writes unit tests for the functionality in version 1.0. After writing the implementation, he runs the unit tests and is assured that the code
works as expected. When Developer B gets the requirements for version 1.5, he also writes unit tests for the new functionality. While writing
the implementation for the new functionality, he runs the existing set of unit tests written by Developer A. Unit tests start failing, and
Developer B quickly sees that the minor code change that he made had negative effects. He makes a different code change and both the unit tests
for version 1.0 and 1.5 pass successfully. The code passes through QA successfully and the new version is released on schedule.
This is the power of Test Driven Development. Since unit tests are put in place from the beginning, developers can feel confident that they can
change existing code without unknown consequences. It is a well documented fact that the cost to fix a defect rises exponentially as the
code moves from Development to QA and finally to production. Running existing unit tests can eliminate the fear of releasing code to the customer that
breaks existing functionality. This confidence means a better product overall, which leads to customer satisfaction and ultimately leads
to a better bottom line.
Decreased Development Times
When the developer creates unit tests that test the requirements of the application, they are creating a contract between the code and the
requirements. The developer must think through the requirements and handle all user cases prior to writing the code. This leads to two major
benefits. First, since the developer must consider both successful and erroneous cases when writing unit tests, there is less of a chance that
the developer will forget to include fringe cases that may not be discovered until the quality assurance phase, or worse yet, once it has been
released to production. Second, since the unit tests provide the coding requirements for the functionality, there is less of a chance that the
developer will include unnecessary code. Once the unit tests have been written, the coding requirements have been satisfied and the developer
does not need to add additional code. This can minimize code bloat and provide the company with a cleaner code base to maintain in the future.
Impacting ROI
Writing software is an expensive undertaking. It may seem like writing unit tests can increase the time spent coding the application which would
lead to higher development costs. Although the developer must write additional code to test the product code, the additional time spent writing unit
tests actually decreases both the time spent performing quality assurance as well as the time writing patches for the product once it has been released.
It also reduces the time to develop future enhancements. By reducing the chance of breaking existing functionality, developers can add new functionality
in future product versions without going through a lengthy regression test phase. This allows the comany to become more agile and more reactive to
customers' needs. This can translate into a significant advantage over competitors since the time to market is drastically reduced.
These are two solid reasons why any development shop should adopt a Test Driven Development methodology. This writer has experienced firsthand the
benefits of using this approach, as well as the consequences of using other approaches. For solid software development that creates a quality product that
is maintainable and easily modified in the future, Test Driven Development is the only way to go.
Copyright ©2006 Synaction, Inc.
|