TDD journeyfolk, let me rattle your cage a little this fine afternoon.
Lemme sketch a common situation for me. I have a problem, not a small one, to be solved in a tech stack I’m not intimately familiar with. Further, some aspects of the problem are things no one on stack overflow has ever done before. They look, on paper, like they might be doable, but there’s no drop-in and very little advice. I’m in this situation where I have to try something — anything — and fuss with it for a while to see if it might work.
Let’s call this the desperate-ignorance mode of working. I am desperately ignorant of the code I’m about to try writing.
And here’s the rattle: get off me about writing some semi-end-to-end test in junit that will prove I understand my problem/solution pair.
It is very difficult to write a good preservable long-lived test of a thing whose syntax you don’t understand, and while it would be nice if I only ever had to work in areas where I have confidence that I even know enough to know what I want, I quite often don’t, due to my role in the team.
So take deep breaths, and give a little trust? Dogma just does not help me.
I have been TDDing more than many have been aware what a computer was. I am a TDDer. I write microtests, I advocate them, I live by them. I am not going to ship code that doesn’t honor the geepaw guarantee. I don’t do that any more. I go faster with microtests. I choose them.
But it’s dogmatic and foolish to ask me to roll a test for a thing whose most basic mechanism I don’t understand, even from a blackbox view. I don’t write tests because God told me too. I write tests because I know what I want and it gets me to that faster.
If I don’t know what I want, I can’t even sketch a test. When I barely know what I want, I can write a huge bad ugly test expensively, one that I don’t like and will throw out the very second I understand what I want.
But don’t get on me about whether I’m a TDDer. I am a TDDer. I won’t let anything stop me from background-working on getting to testability.
I just don’t do that.
"Well, let’s write a test." "Ummm. A test for what? A test that this compiles? A test that I will like it?" I don’t work for the tests. The tests work for me.
I already have a test that it compiles, it’s called "the compiler". And I already have a test that I will like it, it’s called "me". And they’re very fast, very cheap, and very reliable.
When I know what I want my code to do, I will — believe me — learn how to write a test for that. When I know how to test my code, I will — believe me — write the damned test.
I feel folks still don’t understand that these heavy flickery largescale tests are of almost no use in real TDD. They’re hard as fuck to write, & they tell you nothing a run won’t immediately tell you, when you’re a stranger in a strange land.
If I’m starting on something that will be a net of 20-30 collaborating objects. It’s bad practice to write a test out at the controller. When you’re starting something big and new, the outermost layer of objects is by far the hardest to test and lease likely to be right.
Can I write that test later? Yes. Will i? If it helps. But I’m never gonna start there.