Thursday, April 25, 2019

Five Good Reasons to Use Test-Driven Development

This blog post was originally published on the ThoroughTest website, back when that was a thing. As a co-founder and primary content contributor for ThoroughTest, I absolutely own the rights to this post and the source code to which it refers. I intend to reproduce each blog post here on my personal blog since the company is no longer in business.


When it comes to test-driven development, many developers want to know why it is better to write tests before code instead of the other way around. This is a great question and is truly a stumbling block for a lot of people when it comes to climbing on board the test-driven development train. The main way we hear this question phrased is "Why can't I just write my tests after my code is complete so I know what I'm testing?" Of course you can write your code first, and there isn't necessarily anything wrong with that approach. It's just not as beneficial as writing your tests first. In this article we'll discuss the five major reasons why writing tests first is more advantageous than writing code first.

A Better Understanding


The first benefit you'll see when writing your tests first is a more thorough understanding of the requirements. This is sort of an added bonus of test-driven development. It has been our observation that when developers write the unit tests first, based on the requirements, they are more likely to identify shortcomings in those requirements, and are also more inclined to seek clarification. Since the developers haven't written any code yet, they aren't worried about scrapping anything as the requirement gets clarified.

Write Less Code


The second benefit developers encounter is that they write less actual code. In our experience, most developers are willing to dive right in and start writing the best, coolest, most extravagant code they can imagine. As long as what they end up with satisfies the requirements they don't have anything to worry about. The problem with that approach is that the neat bells and whistles we tend to spend our time on aren't necessarily important to the product owner (or end users). When we use test-driven development all the way through the process, we see developers spend time only writing code that satisfies requirements. Bells and whistles can still be added, but they are more deliberately added by creating requirements around them. This actually goes back to the first benefit of test-driven development. When developers understand what the product owner wants it is easier to stay focused on that goal and deliver something that satisfies everyone in the allocated time.

Better Design


The third benefit of test-driven development is that it helps enforce SOLID design principles, which will almost always lead to better code. Test-driven development usually requires some form of dependency injection (D: Dependency Inversion), provide the developer an opportunity to keep classes focused (S: Single Responsibility and I: Interface Segregation), and helps enforce the idea of swapping out concrete implementations at runtime (L: Liskov Substitution Principle). Writing better, more extensible, more maintainable code should always be the goal of the development team, and test-driven development will inherently work to that end.

Faster Development


This brings us to the fourth significant advantage of test-driven development: timeliness. If you've read our guide you'll know that test-driven development goes pretty hand-in-hand with Agile development methodologies. One of the 12 principles of Agile is to "deliver working software frequently" and test-driven development helps with that. When developers are able to understand the requirements better and stay focused on what the product owner wants delivered, they spend less time adding features no one asked for, which shortens the development cycle, which allows more working software to be delivered more frequently.

Faster Delivery


The fifth advantage of test-driven development goes hand-in-hand with the fourth: the overall release cycle is shorter. In addition to shorter development cycles organizations will see shorter QA stages with fewer bugs discovered, shorter user acceptance testing stages, and fewer bugs reported in production. Since the developers and product owner clarified the requirements before any code was written, the QA team has a clearer understanding of what the final software should do. This allows them to create much more targeted tests. There is also the added bonus that QA will find less nuisance bugs (e.g. a system failure when a field is left empty), which requires less re-work and allows the QA team more time to find major bugs. When the product passes QA and goes out for user acceptance testing, the product owner isn't surprised by anything she didn't ask for in the development process. Since the developers received clarification at the beginning of the process, there is less room for ambiguity and fewer reports of issues from users. Finally, once the code does reach production, more bugs have been found throughout the development and approval process, which means there are fewer bugs actually released into the wild. In addition to better uptime and customer satisfaction, this also means developers won't have to stop work on new features to fix user-reported bugs in production code.

So can't these benefits be realized by writing tests after the code is complete? Since all of the advantages we've listed here build off the first one, and that first one provides clearer requirements, there's really no way to duplicate these benefits if we write our code first. Just as it is better to have coded unit tests than to not have coded unit tests, it is better to use test-driven development to write those coded unit tests than it is to write them after the code is complete. Although there are many more smaller benefits of writing your tests first, we feel these five provide the most compelling argument in favor of test-driven development.


No comments:

Post a Comment