The Value of Tests
With a continued rise in delivery expectations, development efforts often skip unit and integration tests to save time and money. We challenge such decisions.
Join the DZone community and get the full member experience.Join For Free
Time is money.
It is a phrase that has been around since Benjamin Franklin put it into print in 1719 — at a mere thirteen years of age.
It is also the mantra that can cause feature teams to take creative approaches to deliver functionality as quickly as possible. One common approach to cut down on time to delivery is to avoid spending time providing code coverage via the employment of unit and integration tests.
For me, this has always been viewed as a mistake — providing a false sense that time is actually being saved. Consider these three examples of where unit and integration tests have provided a significant benefit to the projects they were employed within.
Spring Is Great ... Almost Too Great
The Spring framework, and really Spring Boot, is great! The team, mostly from Pivotal Software, have dedicated their time and efforts to provide a wonderful starting point for application services to be built upon. With Spring Boot, things are really easy.
They are also really easy to do incorrectly... because Spring Boot can be very unforgiving.
My original implementation of JPA Specifications, as discussed in my "Specifications to the Rescue" article, is an example of Spring Boot's greatness that tolerated my not-so-great design.
I coded the JPA Specifications for my project and was getting the expected results from my implementation. I was excited that I figured out this concept that was really going to make life easier for filtering data and introducing multiple filters. My client was already excited when I shared the news.
Then I started writing the tests and realized my design was not something that could be properly exposed and tested. This made me realize that my approach was not the best approach and wondered what kind of issues would have been encountered had I not taken time to provide test coverage for the functionality.
In this case, the updates were minor in nature — with IntelliJ IDEA making the refactoring quite simple.
It is very easy for developers to become focused on meeting the needs of a given feature. When writing code, this focus can cause one to lose track of any gaps that can emerge within the ensuing program code.
Unit tests often expose these gaps, when mocking up scenarios to fully cover the code that has been introduced. Alternative flows — when the test asks, "what about this scenario?" — are first to expose unconsidered logic in the code being delivered.
Once all the flows have been covered, the original design of the program code can require some degree of refactoring. This refactoring has the benefit of happening prior to QA testing and likely avoid production support issues, which would have not been in place had tests not been created.
Racing Toward a Deadline
Unit and Integration tests can actually provide a great deal of benefit when working on a project with a fast-approaching deadline.
When I was part of project with such a deadline, a mandate was employed that test coverage must exist for all work being submitted for pull-request (PR) reviews. This project employed several teams, with all the PRs being completed by a centralized team. That centralized team knew there would be no way to understand and evaluate every aspect of the project. The thought was that proper test coverage would help chase out potential bugs.
In talking with developers now forced to have code coverage, I heard numerous stories on how the test mandate identified gaps in their development that would have not been exposed otherwise. The resulting effort provided a better product as a direct result of the unit and integration test coverage mandate.
How many times have you received an incident/ticket for a bug that was introduced from code that you introduced and your first thought when you saw the issue was something like "what was I thinking?" In those cases, how many times did you have a set of unit or integration tests to validate your design and approach? My guess is that little (if any) unit or integration test coverage existed in those scenarios.
That is not to say that unit and integration tests are safe guards to avoid introducing bugs. Rather, they allow the developer to provide test conditions to fully cover the code. This process often reveals items like questioning the decisions or challenging the implementation path that was employed. In these cases, a better product was delivered to the QA for validation, with a greater potential of meeting the acceptance criteria of the request.
Have a really great day!
Opinions expressed by DZone contributors are their own.