Tech Along blog: TDD to the Rescue

img

 

A great friend of mine opened the Unit Testing and TDD door for me back in 2012. He introduced me to the practice and told me about the benefits of doing it: “… if we do unit tests, we can move safer, with more confidence”, he said. That was the moment my interest in Unit Testing and TDD started.
 

More recently, I hosted a Tech Along knowledge sharing on this topic at Evident and in this article, I would like to share the research I did on the topic and my experience with Unit Testing and TDD.

What is TDD?

Test-Driven development is a well-known practice used in software development where, in a nutshell, the developer writes the tests first, before writing any production code. The practice is all about short development cycles: write your test first, then write the production code to make the tests pass, then refactor.

Short cycles = short victories!

TDD is not a new thing

Even though TDD is associated to the Agile movement, it is not a “new thing”. Back in early 1960s NASA applied an equivalent technique to TDD in the Mercury Project. Eight years later, NATO sponsored a conference where component testing and the testing of computer software were discussed.

However, it took a few decades for TDD to be part of our tech lingo and Kent Beck can be credited for it. Kent says he had “re-discovered” TDD when he wrote the first xUnit framework for Smalltalk, called SUnit.

“It is considered a good agile development practice to think through requirements before writing functional code. “

Scrum.org, Professional Scrum Developer

TDD & me

When I started my career as a software developer, I was writing unit tests after writing the production code and it felt like I was “adapting” the tests to my code. I realized I was not really testing the requirements. The code could be doing something else that was required, and I was certifying it… ouch!

At times, I also found myself in a “how am I going to test this?” situation, because my components were too tightly coupled and I needed to use a whole bunch of extra techniques in order to “certify” the production code. I decided to start doing the tests first and that was the moment I discovered the “magic” of a short-cycle victory.

At first, it was hard to start linking the requirements to the unit tests and understand what the “unit” under test is. It still is. It is hard not to fall into the “test every method” trap and tying your tests too much with your production code, which will make refactoring a nightmare.

However, I believe it is even worse to not be able to release software with confidence and not being able to refactor my code without thinking “I hope I don’t break anything”. So, this is where TDD comes to the rescue.

TDD to the rescue

In the inspect & adapt environment of Agile, practicing TDD allows for the delivery of good quality software. Changes on the production code can be safely implemented and software can be released with confidence. Practicing
TDD favors a deep understanding of the requirements and the resulting unit tests are also a good way of documenting software.

TDD will also help in the design of loosely coupled software components. You will find that the SOLID principles are paramount when practicing TDD. The result: cleaner code.

The trigger to write a test in TDD is implementing a requirement. Test the publicly exposed methods, not the internal or private methods as you will end up with tests that are tightly coupled with the implementation code, making them very hard to maintain.

Be careful…

TDD does not go without controversy. As put by DHH:

“Test-first fundamentalism is like abstinence-only sex ed: An unrealistic, ineffective morality campaign for self-loathing and shaming.“

David Heinemeier Hansson, TDD is dead. Long live testing, April 2014

A commonly used argument against TDD is that it makes refactoring very hard, which is against the promise of TDD in the first place: “… you use TDD to be able to refactor with confidence …”. So, what is wrong?

There is nothing wrong with the practice itself. The issues are usually caused by the heavy usage of mocking and the tight coupling of the unit tests with the production code, which makes refactoring very hard.

TDD should also not drive your architecture, because architecture is a high-level vision of the software application or system that we are building. Applying TDD will not provide that vision because unit tests are close to the code implementation and (again) architecture is a high-level vision of your system.

“Before you begin to code any software project, you need to have some architectural vision in place. TDD will not, and cannot, provide this vision. That is not TDD’s role."

Robert C. Martin (Uncle Bob), TDD Harms Architecture, March 2017

The Takeaway

TDD is not a silver bullet. It is not a tool. It is a practice, it is a discipline and it relies on the developer on how and where to use it.

It takes time to learn and adopt. It will probably slow down your delivery pace in the beginning, but it will help you write better software.

A way to go about it is to avoid testing implementation details as you will end up with tests that are highly coupled with your production code, which will make the test suite very hard to change and to maintain. Also, test the public methods and the behaviors they are implementing.

“TDD is important. TDD works. TDD is a professional discipline that all programmers should learn and practice. But it is not TDD that causes good or bad designs. You do that.“

Robert C. Martin (Uncle Bob), TDD Harms Architecture, March 2017

Finally, and not unimportant: it is fun! Short cycle victories.

image (22)

A little bit about myself:

I am a software developer for 25+ years, passionate about agile methodologies, software development best practices and I love running I work at Evident, a digital agency that helps B2B companies grow in an ever-changing digital world.

Continue learning

Books

  • Test Driven Development: By Example 1st Edition By Kent Beck
  • Unit Testing Principles, Practices, and Patterns 1st Edition By Vladimir Khorikov
  • The Art of Unit Testing: with examples in C# 2nd Edition By Roy Osherove - Working Effectively with Legacy Code By Michael Feathers

Videos

Blogposts

Author:
Evident
We help B2B companies grow in an ever-changing digital world

Evident