DEV Community

Jonathan Hall
Jonathan Hall

Posted on • Originally published at jhall.io on

How I learned TDD (the hard way)

The first time I remember seeing TDD demonstrated was in 2009 at the PgWest conference in Seattle. The talk was demonstrating the pgTAP framework for testing Postgres stored procedures.

I thought it looked interesting, so I rushed home to try it out. I wrote a few tests. I did a little TDD. And I hated it.

The tests I ended up with were brittle. The code I ended up with was hard to use. And most important, it took about 10x longer to write code this way. I quickly abandoned the technique, assuming it must just be for certain people, or certain situations, but it wasn’t for me!

A few years later, I read Michael Feather’s book Working Effectively with Legacy Code, in which he says:

legacy code is simply code without tests.

The rest of the book describes how to get untested code under test. This is a surprisingly difficult challenge in some cases. But after reading that book, I began to gradually write more and more tests whenever I created code—but still writing my tests after my code.

Over time (years, probably), I became better at writing tests. And critically, I began to see ways to structure my code, so that testing would become easier.

Once I started thinking in this new way, the switch to full-fledged TDD was much more natural.

All in all, it took me about 5 years, maybe longer, to go from TDD ignorant, to a TDD “hater”, to a TDD lover and advocate. I hope it doesn’t take everyone quite so long. ¯\_(ツ)_/¯

Top comments (5)

Collapse
 
b0r profile image
b0r

It is really great to see even more people practicing TDD on real projects :respect:

What really helped me to grasp TDD concepts was Dan North's introduction to Behavior Driven Development (BDD) which make TDD even more natural: dannorth.net/introducing-bdd/.

I think it could be really helpful for readers to mention BDD and benefits it brings to the table.

Collapse
 
jhall profile image
Jonathan Hall

I like BDD, but it doesn't apply to every project. And I think that BDD and TDD are very distinct. BDD has a cycle time typically of days, where as TDD has a cycle time of seconds.

Collapse
 
b0r profile image
b0r

Where did you get that idea/notion of BDD? I'm asking because my team applies BDD concepts to define user stories and acceptance criteria (days/weeks, analysts do that), while developers use BDD to confirm acceptance criteria are implemented correctly at unit/integration/e2e level. Developers also write tests in a TDD manner.

It would be great if you could provide a little bit more info/references to the thing you are stating about TDD/BDD or personal experience would also be nice :)

Thread Thread
 
jhall profile image
Jonathan Hall

BDD is usually considered most applicable to user-facing products (i.e web or mobile apps), and teams with non-technical product owners.

For other projects, it can just be unnecessary overhead.

Collapse
 
freddyhm profile image
Freddy Hidalgo-Monchez

Personally, what did it for me was looking at tests as canvases or scratchpads for my application and not worrying about doing things "right" from the minute I write that first line of code. I don't worry about proper names or abstractions until I'm in the refactor stage of the TDD cycle, and even then, it's a very iterative approach.

I highly recommend a video called Play by Play: TDD with Brad Wilson if you can still find it online. It shows this approach quite well.