In this blog

I had been a software developer for over 10 years before my mindset switched to Test-Driven Development (TDD). I must admit that I had the wrong impression of TDD until I started following it every day. My first project, where the whole team was following TDD, was a distributed digital transformation solution. It was released to production without any significant issues after more than a year of challenging work. That was an awesome feeling! I love using this example and sharing that feeling when I talk about TDD, especially with people who still have doubts about this software development approach. 

What is TDD?

TDD is a software development technique based on short development cycles (practiced out of Extreme Programming methodology) with a focus on a test-first approach: you must first write a test that fails, then write the code to pass that test. Refactoring is considered with each test cycle, where the new code is restructured to the appropriate standards without modifying functionality. A cycle could be as short as 10 minutes, however every cycle delivers one small piece of functionality that is required by the larger system. After each iteration, the code should be in a deployable state. If a developer breaks existing functionality by adding a new feature, the developer will get immediate feedback from any failing tests. 

Benefits of TDD

Better quality 

Writing tests first force developers to focus on one thing at a time and enforce modular, testable design. Test-driven code has complete test coverage, which means it always performs the task that it was created to do as long as the test was written correctly. 

Embedded documentation 

Tests are also used as documentation for the code. A codebase with good test coverage is always easier to support for other developers. Better readability of the code helps new team members catch up with the project faster, which speeds up the onboarding process as well as any handoffs.  

Minimize unplanned work  

TDD reduces the number of bugs introduced by software modifications and the time spent by developers on debugging. Developers waste less time spinning their wheels on unplanned work. That also boosts development team morale and overall increases team performance. The importance of minimizing unplanned work is well described in the book The Phoenix Project

Supports agile   

Solid test coverage and well-structured code give the development team the confidence to make significant changes and add new features without the risk of breaking existing functionality. That is a crucial aspect of the agile process. That enables the development team to welcome changing requirements at any stage of the development process. 

Frequent deployments 

Since every new TDD cycle adds new functionality and does not break existing features, the development team can keep code in a deployable state. That allows the development team to deploy an application as often as it makes sense for stakeholders. It shifts the decision point on whether to release software from a technical consideration to a business perspective. 

Maximizing "work not done" 

TDD guides developers to write code, which is just enough to pass the test and just enough to get feedback. That eliminates lots of futureproofing, gold-plating, and dead code. 

Effectiveness of TDD 

A frequent opinion on the effectiveness of TDD is that TDD takes too much time, slows down development, and makes a project more expensive. While it is true that TDD takes longer than writing code without tests, the benefits that TDD affords need to be considered to determine if they outweigh the cost. 

There is a significant amount of research about TDD. Most studies focus on the quality of the product and the productivity of the development team. Quality metrics include the following aspects: design of the system, defects, quality of tests. 

Research from Microsoft and IBM [1][2][3] report a 40% to 90% reduction in defects after introducing TDD techniques into the development process and a 15% to 35% increase in initial development time. 

The research conducted by the IBM Corporation and North Carolina State University [4] was based on a 5-year project. The research concluded that "lifecycle quality improvement would compensate for moderate perceived productivity losses." In other words, quality pays for itself over time. That makes sense, and it is true not only for software development. 

It is worth mentioning that many studies focus on different metrics, and all the studies have their own limitations, so they cannot be used as absolute truth. However, most of the studies about TDD say that initial investment in quality will be compensated by time and resources spent on maintenance. Developers spend more time on development and less time on debugging and fixing defects. Better quality also extends the lifetime of the product. For short-term projects, such as proof of concept projects, the benefits of TDD in some cases may not be obvious. The longer the lifespan of the product, the more benefits TDD affords. 

Is it worth adopting TDD? 

That is another common question about TDD. That question can be split into two parts: what skills are needed to leverage TDD, and how TDD changes the development process? 

Addressing the question about skills, it is fair to say that developers following TDD will work heavily with test frameworks. With that said, it requires the following knowledge: 

Refactoring is a significant part of the TDD process, so knowing refactoring technics would be beneficial. Those skills are not TDD specific. They are broadly utilized in a lot of software development projects. If a team already has those knowledge and experience, it will speed up the adoption of TDD practice. With that knowledge, developers could start learning and practicing TDD mechanics, which can be considered as "TDD specific" skills. It might be beneficial for the team to take some TDD training. Another highly recommended approach is to add at least one developer to the team, which has extensive experience with TDD. Those steps and support from management could help any team to adopt TDD faster. 

The second part of the question refers to changes in the development process. TDD forces developers to focus on the expected outcomes before writing a code to implement a feature. TDD is a very disciplined way of writing software. It requires dedication, especially in the initial stage of the learning process. Like any new process, it may feel awkward but eventually becomes second nature. 

Quality assurance in TDD 

TDD is a software development technique, it is an important part of QA strategy, but is not enough by itself. TDD process decreases defects. That allows the team to shift their focus from manual repetitive testing to quality, which is difficult to prove with automated tests alone. TDD helps a team build solutions and make sure that code is doing what is intended. This enables additional time to be devoted to finding blind spots, and not trivial issues. Using a TDD process allows the team to focus on higher-level aspects of quality such as security, exploratory testing, scalability, performance, localization, etc.  

TDD minimized manual repetitive testing efforts and reduces time spent on bug reports, but it does not replace the need for QA in software development processes.  

Conclusion 

Test-Driven Development is a powerful technique and one of the fundamental agile software development practices that benefit all stakeholders and development team members. We live in a world where business survival now depends on quality. TDD enables teams to build better software and helps protect business investments eventually.

References

  1. E. M. Maximilien and L. Williams, "Assessing Test-driven Development at IBM" in International Conference of Software Engineering, Portland, OR, 2003.
  2. N. Nagappan, E. M. Maximilien, T. Bhat, and L. Williams, "Realizing Quality Improvement Through Test Driven Development: Results and Experiences of Four Industrial Teams" Empirical Software Engineering, vol. 13, no. 3, June 2008.
  3. L. Williams, E. M. Maximilien, and M. Vouk, "Test-Driven Development as a Defect-Reduction Practice" in IEEE International Symposium on Software Reliability Engineering, Denver, CO, 2003.
  4. J. Sanchez, L. Williams, and M. Maximilien, "A Longitudinal Study of the Test-driven Development Practice in Industry" in Agile 2007, Washington, DC.