I know TDD. I know what real TDD is. I know how to do it right, whatever that means depending on the TDD practitioner.
I still don’t like this practice, and rarely use it, except in 2 situations:
- I’m fixing a bug in an existing code base: in this case I’ll write a test first to reproduce and isolate the bug, and then fix it and refactor if needed
- I’m adding a new use case to an existing feature, and will treat the lack of existence of this new case as a bug, see 1.
I don’t ever, ever, EVER use TDD to write new features from scratch. It doesn’t work for me. It doesn’t match my mental model. It doesn’t help me go faster, doesn’t make me produce better code, and doesn’t make me write more, or more useful tests. I don't enjoy it and it doesn't provide me with any kind of satisfaction.
I still have a personal methodology, but it’s not TDD. I still strive to write good test and maintain good coverage, but not doing TDD.
TDD should not be forced upon developers who don’t want to follow it, in the same way a specific IDE should not be forced upon a developer. TDD is a tool, not a goal in itself. The shared goal is to have a well tested code base that is as safe as possible from regressions. How developers achieve that doesn’t matter.
TDD should not be conflated as "writing tests". I often see the rhetoric that, if you don’t do TDD, then you don’t write tests. If I showed you a code base with tests, there would be no way for you to know if they’ve been written in TDD or not.
TDD is not a team practice. Writing tests is a team practice. Code review is a team practice. Automated CI is a team practice. Whether a developer does or does not do TDD has no impact on the rest of the team. I could tell you I'm doing TDD if it pleases you, and you'd have no way to know that I don't, micro-managing set aside.
If in TDD you trust, don’t proselytize it. TDD is a personal practice.
Top comments (3)
I agree in general.
To me, TDD is worth learning in the same way that lots of courses one might take in college are valuable knowledge even if the literal practices aren't used daily. TDD should probably be thought of in that sense.
I think because it's such a religious topic, I feel like it's not treated in such practical terms.
I think so , TDD is tools and use it when need it . but I think TDD is name for more generic tools that do best but when you want to use this tools should select one that proof your needs
Hmmm, I find the term TDD practitioner to be problematic in the same way Agile practitioner is. Agile is simply the philosophy laid out in the Agile manifesto. A bunch of non-technical people took the concept of Agile and turned it into a bunch of process and methodologies with complex (rigid) flowcharts determining how work should be delivered. Agile isn't something you practice, it's a philosophy that informs your work.
The same is true for TDD in my opinion. TDD is a philosophy that you apply to your work.
A few things I (personally) consider to be test driven development:
.http
file or a postman collection after making some changes.All of these things have something in common: they are a defined set of actions that I will perform to verify the correctness of an implementation.
I don't advocate for or against TDD. But I'm lazy and can't be bothered performing all of these actions manually every time I make one tiny change. I'd rather just define the actions once and then let the machine do it for me.
Take HMR as an example: so many front-end project I've worked on implement HMR but don't actually implement it.
You might see some call in the app index like this:
Great! Every time I save a file the browser will reload and all state will be reset. The only module being replaced is the top level
index.ts
module. Everything else is thrown out and I have to point and click at a bunch of things to get back to the required state to actually verify the change.In reality, every module should define some method for its replacement:
This is how you implement HMR, and it gets really tricky and verbose really fast, and after many years of dealing with these kinds of annoyances (and not being given the time to apply HMR effectively) it becomes much simpler to write some tests with a tool like Cypress, wdio or similar:
It's objectively true that running this test allows me to verify the correctness of my implementation much faster than:
In my experience, it's also true that this kind of tooling allows me to do a number of other things that would be very hard without automation:
[insert shiny new technology that a PM heard of so now we should rewrite our entire codebase to use it here]
.This last one is the biggest boon for me personally. Whenever I receive a QA test plan, my first task is to define these as automated tests. This frequently helps me avoid missing details in the acceptance criteria. If the QA test plan fails, then these tests fail, meaning the implementation is not ready for testing.
If you haven't read Kent Beck's Test Driven Development: By Example, I strongly encourage you to pick up a copy. He's the person who developed TDD originally, and you'll find that his opinion is much aligned to yours. TDD as a paradigm is just an approach you can use to verify correctness.
I'd challenge you to read the book, then attempt to cover the public facing facets of a project you're working on just for kicks. You'll find the process illuminating.
From the book's preface:
If Kent Beck doesn't advocate for TDD first for everything then anyone who says so should probably read this book also :)