Test-Driven Development (TDD) has been a proven and powerful design and development techniques to create high quality product in agile environment. Agile teams embracing TDD thought-process to design and implement their product features have realized significant improvements in code and design quality. TDD increases reliability in software development. TDD driven teams are more likely to meet their User story Done-Done criteria’s for a sprint. They will be able to reduce re-work waste while development, and maintain the flow during iteration. TDD development is always guided and supported by tests. Above all, TDD approach leads to beautiful code – testable, maintainable, extendable and readable.
Following are some experiences (with limited explanation) of TDD practicing agile teams:
1. Improved Code Quality
- TDD helps in creating code that flows better; code that’s easier to understand and use; code that expresses what it does and why, instead of how it does it.
- TDD driven code is clean and lean. Minimal code with optimum design gets written when team develop TDD way.
- TDD ensures high quality maintainable code. Well maintained code leads to low re-work and less efforts when extensions and modifications are required on exiting code.
- TDD produces testable code by making the code cleaner, simpler and less complicated. Production code is always testable because it is written in confirmation with the test code.
- TDD improves the readability of the code. Developers continuously re-factor the code to make it more readable.
- TDD reduces programming errors. Since the code is continuously tested, programming errors are reduced.
- TDD helps us write thoroughly tested code, and evolve our code with the best incremental design possible at each stage. Test written before the code helps developer to experiment and evolve the code in right direction with controlled quality.
- TDD helps in avoiding production code explosion. Unnecessary redundant production code does not get written. We build the simplest thing that is needed now and discourage speculative development.
- TDD leads to testable, maintainable test code along with production code. TDD drives continuous re-factoring of test code along with production code, which leads to high quality, low maintenance test code.
2. Emergent Design and Architecture
- TDD leads to good emergent design. It helps developer to think about the code from the perspective of other (existing and non-exiting) code that will use it. It promotes emergent incremental design. Design emerges as production code is written in incremental steps, guided and experimented with tests.
- TDD guides development to right design and functionality Developers can avoid coding big requirement and design at one go. Requirements and design gets translated incrementally into well behaved code.
- TDD discourages “Big Design Upfront”(BDUF). It gives opportunities to do design changes incrementally, while developer codes the feature.
- TDD simplifies the components and object design by simplification of association and relationship consideration between objects.
- TDD helps in avoiding over-engineering of system design. Short feedback test loops reduce the traditional bulk implementation approach.
- TDD provides continuous feedback to drive improved implementation of design with executable tests.
- TDD design is usable and always testable.
- TDD enables creation of short composed and cohesive methods and classes. Composed methods are short and easy to test-methods which perform one single identifiable task.
3. Agile Testing with Quality Test Code
- With TDD, tests “Do get” written. No postponements.
- TDD helps in building a suite of repeatable regression tests as we develop the product code. Regression testing time is reduced significantly with well-designed tests.
- TDD leads to high and effective code coverage for unit tests.
- TDD coded tests become requirement specification documents – ‘Test as Specifications’. Test serves as documentation for understanding the implemented product features.
- In TDD enabled environment, there are no unit test explosion. Unnecessary redundant unit test don’t get written.
- TDD helps in ‘testing the test’ to ensure effective unit tests are getting developed.
- Unit test written with TDD approach are well re-factored and maintainable.
- Tests written through TDD will have fewer bugs.
- TDD drives implementation of design with executable tests.
- TDD tests are simple and focused on required and essential functionalities only.
4. Agile Software Development Practices Improvements
- TDD enables “Programming by Intention“. It makes the developers intention clear by focusing on the actual requirements.
- TDD enables iterative, incremental and reflective development and testing with short development cycle – feature by feature.
- TDD helps us write better software faster.
- TDD leads to test infection – development becomes test infected.
- With TDD, user stories acceptance gets coded before the actual implementation. It helps in creating executable test suite and leads to “Test as Specification”.
- TDD increases collaboration with Product owners. TDD developer is quickly able to test different viable options providing early feedback to product owners on the user stories. It will lead to better and more complete acceptance criteria’s for user stories.
- TDD get the User stories closer to definition of “Done-Done” by ensuring all acceptance test cases have been coded and have existence in executable form.
- Code re-factoring is not left for the end. It is done as part of development.
- TDD enables continuous collaborations between developers. Developers develop empathy for other developer’s code in the team. They tend to collaborate early to clarify the integration and dependency needs.
5. Creative, Thoughtful and Fearless Developers
- TDD enables developers to experiment with design and implementation options by continuously simplifying code and design changes. Developers can make quick changes while developing the code; they can test it in parallel, and gauge the required feasibility of design and code. Tests acts as safety-net for code experimentation; enabling developers to be more creative.
- TDD focuses the developer on acceptance criteria’s of the user story.
- TDD helps developer to code without fear. Tests provide the safety-net and act as a baseline for improvements. Developers become fearless to experiment and improve the code and design quality.
- TDD exposes a gap in understanding of the developer about the functionality. Since the code is developed incrementally, guided by tests, requirements gaps are identified and filled quickly.
- TDD developer does more and better code re-factoring.
- TDD focuses the developers on the incremental requirements detailing and implementation; avoiding quick, thoughtless code development.
- TDD limits and guides developer assumptions – Note: assumptions build on assumptions. Assumptions verified through tests helps in better decision making by developer. Design assumptions are only followed when proved by passing tests.
- TDD simplifies complexity handling for developers. Incremental development approach of TDD helps in simplifying the complexity inherent in large batch development by continuously providing the feedback loop to developers.
- TDD focuses the developer on what is absolutely needed right-now, then making that tiny piece work, and finally cleaning up any mess she might’ve made while making it work, effectively keeping the code base healthy.
- TDD leads to increased developer learning and understanding of requirements!
- TDD developers are more confident and creative in design and implementation.
- TDD developers are always in control and at fun!