DEV Community

Cover image for 4 reasons I fell in love with Test Driven Development.

4 reasons I fell in love with Test Driven Development.

Patricio Ferraggi on December 20, 2019

If you are interested in reading this article in Spanish, check out my blog The Developer's Dungeon Until 2 years ago I had never written a single...
Collapse
 
190245 profile image
Dave

My issue with TDD is the time component, and PMO always have immovable deadlines...

The typical workflow is that you sit in a planning meeting, talk about the tasks, figure them out & put story point estimates on. Back at your desk, you pick up the first task in the TODO column & recheck the requirements. Work begins.

While working on the task, previously unknown parts of it start to get clarity. The complexity of the task changes (but the estimate never does). At some point, a BA comes over with "oh by the way, they don't want a Ferrari, they want an airliner, you can do that in the same timeline, right?" So we have to refactor everything.

If I used TDD, I'd have to refactor both the tests and the code that fulfils the requirements. If I write unit tests as I go, I have to refactor the code and the tests. If I write the tests last, I only have to refactor the code I've been writing.

Tests are the first thing that PMO sacrifices for the timeline, because they're only seen by developers, and we pay QA for testing anyway, right? So why are we paying devs to test too?

Refactoring more things takes more time, especially when requirements exist in a shifting sands environment.

Collapse
 
dan1ve profile image
Daniel Veihelmann • Edited

Developing without tests will save you time in the short term, no question.
However, having a test suite will save you time in the long run, because it can catch bugs immediately.

In addition, it will let you ship with confidence. You can literally proof that the tests workflows work.
To me, this psychological effect is even more important and let's me sleep at night ;)

Collapse
 
190245 profile image
Dave

Nowhere in my post did I say that products ship untested.

The debate is about either writing tests before code, or code before the tests (TDD or not).

Thread Thread
 
patferraggi profile image
Patricio Ferraggi

Hey Dave, sorry maybe I misunderstood, then what did you mean by this
"Tests are the first thing that PMO sacrifices for the timeline, because they're only seen by developers, and we pay QA for testing anyway, right?"

Here I understood that in some cases PMO decides not to test in order to meet the deadlines, is my understanding of your answer incorrect?

Thread Thread
 
dan1ve profile image
Daniel Veihelmann • Edited

Dave, fair enough, maybe I misunderstood your post.

However, from my (and my team's) experience, writing the production code before the tests will often lead to code that is simply hard to test.

I don't follow TDD strictly, but I certainly see it's value, especially for bug fixes.

Thread Thread
 
190245 profile image
Dave

No argument about TDD for bug fixes - you get clear, unchanging requirements in a bug fix. I personally follow TDD when fixing bugs.

Re the untestable code - I think that's something that just takes time. We have a few guys who write then have to refactor to write unit tests.

But (in our case) you can hit the minimum coverage targets by writing integration tests, and somewhat disregard good OO design principles and code patterns, and it'll still pass a build (though we tend to complain loudly in code review about future maintenance, and usually a PM interjects with "raise a tech debt ticket, we'll fix that in future, I promise" 🤔)

Collapse
 
stuartplowe profile image
stuartplowe

Unit tests are not optional, unit tests also make programming so much more enjoyably. Hacking with confidence, not by coincidence

Collapse
 
patferraggi profile image
Patricio Ferraggi

Indeed, it took me years to figure that out though 😔

Collapse
 
Sloan, the sloth mascot
Comment deleted
 
patferraggi profile image
Patricio Ferraggi

Yes I feel exactly the same, luckily that is were I am now.

Collapse
 
jeastham1993 profile image
James Eastham

Great article Patricio! I've been on a very similar journey (never having written a single test in the first few years of my career). One of my goals for next year is to fully embrace TDD. Although I know I should use it, my usage is still sporadic.

That said, the one service I have written recently in which I've fully embraced it is incredible. The service validates a set of data points, and currently there are 150+ different combinations and outcomes. I can refactor with confidence because I know all 150+ cases are coupled with a specific unit test.

Collapse
 
patferraggi profile image
Patricio Ferraggi

Yeah it's hard, I have been focusing on doing it and I still struggle, but as you said, when you start noticing the benefits in things you made is when you get hooked

Collapse
 
fly profile image
joon

Loved the analogy with dating :)
Also 'legacy code is code without tests' felt very insightful.
Thank you for the post Patricio!

Collapse
 
patferraggi profile image
Patricio Ferraggi

I am glad you like it, indeed is a very good one, I recommend reading Michael feathers book, "working effectively with legacy code", is game changing.

Collapse
 
toonarmycaptain profile image
toonarmycaptain

I'm not against TDD by any means, but your initial issue - tests passing for different reason - can often be prevented by having tests you expect to fail eg test: expected to fail: assert add(2+2) = 5 -if this passes, there's something wrong with your add function. This is also useful for confirming you're using a test database rather than production, are accessing mocked elements rather than an internet resource, etc, and in general grouping your tests into things that should and shouldn't happen (which is a helpful paradigm for me), and a gentle nudge that some of your tests might not be testing what you expect (gentle in that an unexpected pass might not fail a build).

Collapse
 
laughingraven profile image
Laughing Raven

There are way to many programmers and not enough engineers. Software should be built the same way one builds a bridge. You would never build a bridge using tdd so why build software that way?

Collapse
 
patferraggi profile image
Patricio Ferraggi

I agree with what Daniel said in some sense, the fact that we re doing engineering doesn't mean that we need to do stuff the same way. Also, when you build a bridge you usually build prototypes to calculate stress conditions and time pressure against natural elements, all before laying the first brick. In this regard I also think developing software is more similar to accounting in the way we backrest our assumptions.

Collapse
 
leo_john_ashwin profile image
Leo john Ashwin

Have you ever got a requirement to reduce the size of one of the pillar in a bridge after it is constructed?

Collapse
 
dan1ve profile image
Daniel Veihelmann

Because developing software is completely different?
Analogies can only help you so much...

Collapse
 
codermikky profile image
Sai Deep Konduri

Wasn't it time consuming? For me it took 20~ 40 % extra time and also it's hard to get used to 🥴

Collapse
 
dan1ve profile image
Daniel Veihelmann

You also save time for future big fixes. In my experience, it's well worth the time.

Collapse
 
patferraggi profile image
Patricio Ferraggi

Why did it took more time to do the test first than last?

If you are comparing test to not test sure it takes longer but the benefits are clear.