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.
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.