Recently posted on Code Project:
I’m just now trying to adopt my thinking to Test Driven Development mode and I’m finding strange, inconsistent, and bizarre things happening in my thought processes and code in some ways as well. Is this pretty normal when you first try to learn TDD?
And as usual, this got me thinking. My response:
Yes. TDD is for the birds, but even they didn’t first write tests to figure out if wings could support them, and then developed their wings.
In other words, TDD is in many cases ridiculous because it requires that you write code to test something you haven’t written yet.
The mindset for writing tests is orthogonal to writing the code you are going to test. When you do the latter, you’re thinking about abstraction, decoupling, performance, optimal structures, and, here’s the clincher, you’re thinking (or should be thinking) about how to structure the code so it can be tested.
When you’re writing the tests, you’re thinking about edge cases, parameter validation, exceptions trapping, whether the business logic is correct, and here’s the clincher, you’re thinking about how to ensure that all code paths are actually exercised.
Now I ask you, how can you test that all code paths are actually tested when you haven’t written the code?!?!?!
So of course TDD is a mind f***. It’s a different process, and it’s often a BAD process. Of course there are cases where you can write the tests first, but certainly in my experience, anything other than a very isolated piece of business logic, it doesn’t make sense. The main result of TDD ends up being that you’ve written a bunch of useless tests, and even worse, you’ve written code to meet the structure imposed by the test.
So what should TDD be then, you might ask? Well, it should be a concept of what needs to be tested – is it algorithm correctness, is it performance, is it multithreaded support, is it worth testing? Then write the code with the idea in mind of what you are wanting to test so that the code is testable, then write the tests.
Mark_Wallace on the Code Project also had an excellent response:
TDD is extremely good for two things:
0. Getting loose cannon devs on track.
We all know and have to deal with such guys, but it’s not hard to write tests with premises like “This is the name of the output module, and these are the expected outputs from it”.
— You know your inputs
— You don’t care what the processes are; that’s where you rely on other developers
— You know the outputs That Have To Result.
So write tests for it.
What TDD does is get that clear in everyone’s mind, so flying off in weird and unwanted directions is less likely to happen.
1. Forcing specs
For me, this is their primary function. Even “produce working code” is secondary.
Put it this way: It’s a way of introducing specs when the f***ing lazy management team hasn’t provided them — with the added bonus that the f***ing lazy management team has to sign off on it.