I’ve been shocked by the TDD backlash. “It’s bullshit.” “It’s impossible.” “You can’t make me.” Somebody must have hurt these folks badly. Now, it turns out Soundararajan was asking their question in good faith (see the end for a comment not made in good faith). We agreed that “use it when it makes sense & not when it doesn’t” was a reasonable strategy.
Unfortunately, most of the developers I have worked with had either never heard of TDD, or thought it a ridiculous concept. Yet those same developers were often terrified of the code and took ages to release any change, because they wanted to make sure there were no regressions (either through manual tests, or static analysis of their changes).
Some may sneer at the "Ease" outcome, but my anecdotal evidence suggests that most programmers have more anxiety about changing their code than they would like to admit.
So much compressed toxicity in a single sentence and then accusing you of that , talk about reality bending.
I have seen elsewhere on youtube comment that you are trying to "shove TDD down our throats" my god...
At least he got one part right you are definitely influential , please keep up your work.
Having practiced and proselytized TDD for 20+ years (I bought TDDBE when it was hot of the presses), the most common reaction I hear ( with whatever rationalization layered on top ) is that TDD "feels weird". It think a big part of that is the way TDD slows you down, since most devs pride themselves on thinking about 5 things at once, and enjoy the rush of keeping all the balls in the air.
There is definitely a learning curve to the practice, and it requires a bit of discipline at the start, but it is the single most powerful technique for programming that I have ever learned.
I usually recommend to people to do what I did originally: find a small project and commit to totally strict TDD, accepting that it will feel like kindergarten at first.
Like any advanced technique, it takes some time to get used to and master, and once you are in the swing of it, you can tailor it to the rest of your style.
Thank you for the post. An outcome that TDD brings me is to help the design process. I feel more comfortable choosing names and making decisions for classes/methods/parameters when I write them first inside a test case.
What happens with TDD, also with Agile in general: Deeper truths and values that make overall sense lead to a certain set of techniques that apply in a given context. Over time, some people forget about the truths and values and focus solely on the techniques. Applied to different contexts, those techniques fail. It is then deduced that the techniques are BS.
I suspect the anti TDD crowd is individuals working in large companies. When you're working in a large company you have a bunch of other developers and dog-fooders to tell you when your code is broken. So the cost of the feedback loop is lower than when you're a solo dev (me!). It's still higher than having it caught immediately, but not as bad. Now this cost doesn't include the broader cost to the company, but just the cost to that one individual.
In my case, as a solo dev, if I introduce a bug, it might take weeks or months before I catch it or figure out the root cause, by which point I've forgotten the context of the change. The cost of a bug is crazy high, so I have to delay features with a much more higher focus on reliability than if I were at a large company. Hence I'll take the small cost of writing tests first.
It's great to see a "Known restrictions" text from one of the main proponents. I did not look through all the comments, but it seems to me the "Cost vs. Benefit" aspect is missing.
From my restricted point of view (SAP development at an SAP customer) I think the following aspects are important (all pertaining to TDD, as well as UnitTests in general - so maybe this is off-topic here):
- How frequent (if at all) will the code be changed in the future? How likely is it that this will break anything?
- How likely is it that critical errors will be overlooked (in initial test, and in future code changes)?
- How hard (how much overhead) is it to write the tests, especially to provide test data / mocking?
- What is the ratio of "real errors" caught by the tests, vs. adaptions to the test methods?
- How much time (and knowledge) do these adaptions to the test methods take?
My team adopted TDD this year and I am now a huge fan (on the other hand, I've written on here a couple of times about TDD and gotten mixed reviews after sharing with Reddit and Hackernews).
Automated tests have caught SO many issues for me before going to staging, and they let me know where all the breaking changes are when I do change something. I'm a lot less anxious about changing things because of it.
I think there's another important point to bring up here though - if your code coverage isn't high enough, it won't catch some breaking edge cases, which reduces developer confidence in the test suite as a whole when either QA finds a bug or the tests don't catch a breaking change ("What's the point of writing all these tests if my software is still buggy and untenable??").
If there's one thing I've learned, it's that TDD is a culture which has to be adopted in its entirety in order to work. I believe this is the hardest part, because you have to constantly be on your team about practicing it - which unfortunately for them includes sending back PRs due to missing tests.
But in the mean time, I'm going to enjoy the serotonin boosts from the tiny green success toasts.
I totally agree with the desired outcomes, but I don't use TDD. I have tried the approach numerous times in my career, but I find I waste time rewriting both code and tests. I can achieve the desired outcomes, including full test coverage, more quickly without TDD. But that is "just me". For others, TDD may be helpful. So I don't think anyone should disparage the pro-TDD nor the anti-TDD crowd. I've been coding for 40 years. I am good at it and passionate about it. If you ask anyone I've worked with I'm sure they will tell you my code is great. It is not about the path we take to get the results, but the results that are important, at least to me.
Great post and great discussion - thanks everyone!
Also, "Bless your heart." Are you a Southerner? 😉
And TDD gives me user empathy because it forces me to be a customer of my code to ensure the interfaces make sense and work well. I find the cost of those kind of issues also fairly high (without TDD)
"An influential autistic developer" is a pretty ableist* statement. WTF. I don't know who is being accused of being autistic, nor do I think their autism is relevant because I absolutely know LOTS of non-autistic software developers who swear by TDD. The advantage of test first is, you are then guaranteed to be able to test the refactored code. That is a selling point. Lots of people, especially under time pressure certainly don't test after. *I am up in the air about "wokeness" sometimes but it's still rude and unprofessional for people to make statements like this.
I have to ask, Kent: you present a very calm and compassionate response (not reaction) to all this backlash (especially "Frank"'s comment you shared at the end). Do you start out with a negative reaction that you then walk off, and get to a calmer state? Or have you reached the zen state already? Cause i'd like to get there too :)
it's a tough situation because i'm assuming Frank is a geek (developer), not an uninformed executive, so he needs to feel safe in the world.
But the "use it when it makes sense and not..." is tricky. people resistant to using it very quickly jump to "it doesn't make sense here". In the specific case of ETL, at one client, though we started out with tests AFTER the fact, after we had built simple, atomic tests for existing transformations, we were then able to use TDD for the newer cases/changes, because most of the fixtures were in place, and it worked beautifully.
Great article. I love this part: "You & your customer deal with the consequences."
Maybe we, as a developer, we don't see the consequences as we should. Most of the time they are not visible to us in a clear way.
So we may think that a cool practice like TDD don't bring much value because we are "safe" the way we work.
I love TDD, but maybe I have this opinion because I had a direct contact with my client and users. And I dont want neither of them sad or mad about my work. The consequences were clear to me and my team. So, we love TDD and testing in general because, in the end, we got happy customers. And we could work in a sustainable way.
TDD helped a lot in understanding the problem before solving it. We developed an ability to question every important details that we could miss before the practice of TDD in the team.
I wish more teams and individuals had this experience.
I like to use my tests as a contract with the stakeholders. I'm a Ruby on Rails dev, and I find RSpec, written well, can be read by "normies" before the "it" blocks are full of assertion code.
This often drives the discussion of "happy path/sad path" in directions folks don't normally think about. Plus, collaboration in this way will often net a tighter solution to the problem the feature aims to solve.
So, that said, TDD is not only good for us code nerds, but serves as a bridge of communication as well.
My issues with TDD are that I tend to think top down and it doesn't feel natural. I however do love the idea of it in terms of having the code coverage allowing easier refactoring and would love to try working on a project with TDD in place.