A colleague recently asked me what my thoughts are on TDD, so I thought I’d spend some time writing up my ramblings to share with you. Expect it to be pretty unpolished, try not to judge me too much for it =]
TL;DR: Some of it’s good, some of it isn’t. Shock!
TDD – test driven development – I’ve never been part of a team that does it, so any thoughts I have are really based on what I’ve read about it, or heard from other people. My basic knowledge and assumptions at this point are that:
1. It starts with writing a test that you intend to fail in order to prove that something doesn’t already do a certain thing. Run the test to confirm failure. Then write code to make that something do that thing and confirm by running the same test – which should pass this time. Repeat.
2. All the tests are automated.
In theory, designing and building new features around tests is a good idea, as it encourages you to create something that can easily be the subject of testing, presumably also often simplifying the feature or code to meet that criteria. This is really appealing to me as, in my short time as a tester (approximately eight months), I’ve already seen my fair share of stuff that’s really challenging to test because it’s so complex, or has hidden features / logic. This can lead to poor visibility and reported “bugs” being bounced back with the old, “the code is written to do that, so it’s not a bug”. Yes, most bugs can be traced back to code, thanks, software only does what it’s programmed to. However, if there is no apparent reason for why it would have been programmed to do something, and no one can even offer a nonsensical, yet definite, reason why it’s designed to do that, then it’s still a bug until we “fix” it then realise where the connection was when it breaks something else seemingly entirely unrelated. In the end, what’s likely to happen is that someone needs to decide whether to revert the “fix” and leave the code as it was before – still without proper documentation to explain it, of course – or invest time rebuilding the whole thing from scratch to make it simpler and cleaner.
That situation is completely hypothetical, of course, and no one has ever actually heard of that happening…
I digress – essentially, testability is good, and TDD seems to encourage that.
However, where I do see a big risk is in the reliance of automation in testing. Again, it’s just my assumption that this is the way it works. You guys can comment and let me know if this is the case, or if exploratory testing is also used in TDD. I guess the crux of what I’m getting at here is similar to the complaint that many people have of the western education system. Have you ever thought, or heard people say, that schools and universities just coach students to pass the tests, as opposed to actually teaching them anything of value or encouraging them to think for themselves? And on top of that, the quality of those tests aren’t even that good, and probably cite the “correct” answer as something outdated or widely discredited? There’s even a certain body in the testing industry that I’ve heard being accused of the same thing. I won’t spoil the mystery by telling you which.
Hopefully you’re starting to see what I’m getting at. By working in a way that means you’re only trying to pass the tests you wrote and having no other considerations, are you really building software in a sustainable, quality manner? Or do you just end up “cheating” the system and manipulating the code with the sole purpose of making sure that a specific set of predefined tests no longer fails? This continues long after the feature has been “finished” too. Say you’re re-running all these tests as part of a regression suite and a few fail. You assume it’s just because the tests haven’t been updated recently / properly and manipulate the tests this time to pass against the unchanged code. It’s a bit like if your crush asked what your favourite colour is and you said, “good question – what’s your favourite?” just so you can say, “me too!” regardless of their answer. I think it is anyway, but I’m open to being wrong…
I think I’ll wrap things up now before I really start to ramble about something I have no personal experience of – and if I did that, I would be the first person ever to do it, obviously. It seems that my reservations around TDD all stem from my reservations around the “automate everything” proposal. But, like many other frameworks and best practices, etc., I don’t think any one thing will ever be suitable for everyone, or even the majority. We don’t have to strictly stick to one methodology just because it’s popular or someone we respect seems to like it. When someone asks which one you practice, you don’t have to be embarrassed to say, “our own”. Give it a name if it makes you feel better and say you invented it, but an exact copy of what you do won’t be suitable for everyone else either, even if it works great for you.
I was thinking about the topic of methodologies as a whole recently, and I realised that more knowledge and experience of methodologies, testing, business… It doesn’t give me more answers to anything, it just makes me a lot more comfortable and understanding of the fact that the answer to a lot of our questions in the testing community are “it depends”.
Does TDD work? It depends. Is TDD suitable for our business? It depends. What are my thoughts on TDD? It depends.
I’m interested to know what you make of it all. Please tell me your “it depends” thoughts in the comments – or if my assumptions are totally and completely wrong – and let’s push each other to consider other perspectives.