What is Test Driven Development (TDD)?
Test driven development (TDD) is a software development practice that involves software requirements being converted to test cases before software is developed, writing a Unit Test before any code is written, and tracking all software development by repeatedly testing the software against all test cases. This is as opposed to writing feature first code, where software is developed first and test cases created later.
A key benefit of test-driven development is that it makes the developer focus on requirements before writing code.
Test driven Development helps with requirements discovery, clarification, and communication. Customers, domain experts, or analysts specify tests before the features are implemented. Once the code is written, the tests serve as executable acceptance criteria.
In software projects that are done without test driven development, mistakes in the specifications may not be detected until deployment. At that point, they can be very expensive to fix (in some cases up to 100 times more expensive).
A Cutter Consortium survey of companies about various software process improvement practices identified TDD as the practice with the second-highest impact on project success (after code inspections).
Programmers can also apply the test driven development concept to improving legacy code that was developed with older techniques.
Test driven development drawbacks
TDD is not a silver bullet. It needs to be done properly and it takes more effort up front (typically between 15% to 20%). Effort that is rewarded with more reliable, better quality code, that is easier to maintain. Effort that is more than offset by preventing defects that are much more difficult and expensive to fix at later stages of development.
Unit testing alone does not perform sufficient testing in applications where there are user interfaces, programs that work with databases, and some that depend on specific network configurations. Separate integration testing will be required.
TDD calls for clear requirements and that the developer understands them—otherwise, unit testing may not be effective.
Unit tests are typically created by the developer who is writing the code being tested. Because of this, the tests may share blind spots with the code. For example, if a developer is not aware of specific requirements, such as certain input parameters must be checked, most likely neither the test nor the code will verify those parameters. Another example: if the developer misinterprets the requirements for the module they are developing, the code and the unit tests they write will both be wrong in the same way. Therefore, the tests will pass, giving a false sense of correctness.
Test Driven Development benefits
Test driven development offers more than just simple validation of correctness, done correctly it guides the design of the application.
By focusing on the test cases first, the developer must imagine how the functionality is used by clients (in the first case, the test cases). So, the interface is considered before the implementation.
TDD can lead to more modularized, flexible, and extensible code. This effect often comes about because the methodology requires that the developers think of the software in terms of small units that can be written and tested independently and integrated together later. This leads to smaller, more focused classes, looser coupling and cleaner interfaces
Automated tests resulting from TDD tend to be very thorough: they detect any unexpected changes in the code’s behavior.
Improves quality and reliability. The ability to write testable code is one of the most important factors that determines whether your software will be reliable and of high quality. Testable code can be verified programmatically and in a very granular way. Because test driven development requires tests to be written before the code, it ensures the code is testable and guides the design of the software.
All other code quality metrics are reflection of its testability.
Produces highly functional software. TDD shifts the focus from implementation to the interface of the software components. Through its test-first approach, it gives developers the opportunity to consider more carefully the functional requirements. With TDD, it’s easy to spot functionality issues as the software is being developed, which allows for them to be more quickly addressed. Software built using the TDD approach is inherently functional —otherwise, it simply wouldn’t pass unit testing.
Reduces bugs by up to 90%. In a report titled Realizing quality improvement through test driven development : PDF, the engineering teams at Microsoft and IBM concluded that “the pre-release defect density of products decreased up to 90% relative to similar projects that did not use the TDD practice.”
The TDD approach extends the assertion Boris Beizer made in 1983: “The act of designing tests is one of the most effective bug preventers known.”
The early and frequent nature of the testing helps to catch defects early in the development cycle, preventing them from becoming expensive problems in later stages.
Tests ensure that the code stays clear during each stage of development. Automated tests quickly reveal mistakes and their impact on the system, which in turn enables developers to immediately detect bugs that arise as a result of the changes they have most recently made to the code. It becomes easier for them to create software that is solid and works as intended and move on to the next unit of code with justified confidence.
Simplifies the code. TDD done right, requires developers to write just enough code to satisfy test requirements. This approach promotes the simplification of code. It can prevent code bloat and helps keep the codebase clean and easy to maintain.
Checks the quality of the code. Tests create quality metrics for the code. Automated tests quickly and effectively determine the quality of the individual units of code as well as ensuring the general health of the whole system. Offering reasonable confidence that no part of the code is broken.
Creates extensible software. TDD encourages developers to build software using small units of testable code. This modular approach to software development contributes to creating software that’s more flexible and extensible than that built using other methodologies.
Provides quick feedback. Fast iterations mean that developers can receive feedback more quickly than with other approaches to software development. Quicker feedback results in faster development, because time isn’t wasted tracking down and fixing bugs. In some cases fixing these bugs could require the redesign of significant parts of the application.
Creates up-to-date code documentation. Test are self documenting and act as complete and thorough documentation for the system. Other developers can use completed tests as usage examples for the code, allowing them to become familiar with it faster. This can make the project more friendly for developers other than those who built the system. For long-term projects which may pass through multiple hands, this documentation can be valuable.
Shortens the development time to market. The writing of tests then code approach, increases the productivity of the development team by focusing their energy on passing tests, i.e., accomplishing goals. TDD enables you to develop a reliable, functional piece of code for end-users in a shorter period of time than many other programming practices. This is a major advantage in today’s competitive software market, where time to market is one of the key factors that determine success.
Test Driven Development procedure
Writing the tests first: The tests should be written before the functionality that is to be tested. This has many benefits. It helps ensure that the application is written for testability, as the developers must consider how to test the application from the beginning rather than adding it later. It also ensures that tests for every feature get written. Additionally, writing the tests first leads to a deeper and earlier understanding of the product requirements, ensures the effectiveness of the test code, and maintains a continual focus on software quality.
Each test case should fail initially: This ensures that the test really works and can catch an error. Once this is shown, the underlying functionality can be implemented. This has led to the “test-driven development mantra”, which is “red/green/refactor”, where red means fail and green means pass.
Test driven development constantly repeats the steps of adding test cases that fail, passing them, and refactoring. Receiving the expected test results at each stage reinforces the developer’s mental model of the code, boosts confidence and increases productivity.
- Create a new unit test based on the requirements.
- Run all tests. The new test should fail as no code for it is implemented yet.
- Write the simplest code that fulfills the requirement and that passes the new test.
- Run all tests. All should now pass including the new test. If any fail, the new code must be revised until they pass. This ensures the new code meets the test requirements and does not break existing features.
- Refactor to optimize and clean the code. Test after each refactor to ensure that functionality is preserved.
The cycle above is repeated for each new piece of functionality. Tests should be small and incremental, and commits made often. That way, if new code fails some tests, the programmer can simply undo or revert rather than debug excessively.
Software requirements need to be clear and understood in order for tests to be effective.
TDD needs to be done properly and it takes more effort in the beginning to do so.
The benefits of Test Driven Development far outweigh the drawbacks.
For developers experienced with TDD it makes software development easier and faster. Resulting in a higher quality product that is more reliable and easier to maintain.
In addition to using coding standards, Test Driven Development is one of the easiest ways to ensure reliable high quality code.
At Nexus Software Systems, Test Driven Development costs you nothing extra and saves you a lot in terms of development time, bug fixing maintenance and greatly improves the quality and reliability of your software.
Of course, you don’t have use TDD or choose a software development company that uses Test Driven Development, you are free to use any software development method or company.
Contact us to learn how your software project can immediately benefit from Test Driven Development.
References: Test driven development