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.
I tried very hard to understand this post. TDD is all about design. Feedback gives you opportunities to know when your production code is couple (too hard to test). The Blue phase of TDD is where you apply your programming design skills. TDD doesn’t dictate perfect design, you do. Yes I’d suggest you try building an application via TDD first (and don’t skip the blue step ever). Then you’ll see what it’.
I also highly recommend you check out my new site, which companies and teams where TDD does work, talk about how they do it. There is no need to prove that TDD works anymore, there’s plenty of proof, and we’re getting more and more of that. This industry is past the “Does TDD work?”. And our profession is at the point of less debate, and more trying out TDD now.
WeDoTDD.com
Hi Dave,
Thanks for reading and commenting. Your comment does seem very focussed on the perspective that TDD “works”. As the title suggests, this post was simply a recording of some thoughts I’ve had about TDD and I’ve never claimed that it does or doesn’t work. I’ve also explained early on that I have no personal experience of working on a project where TDD is used, so I don’t claim to be an expert on it at all.
In fact, one of the best things that has come out of my admitting I don’t know much about this subject is members of the community coming forward to help me learn more, including yourself. Nothing else I’ve read or discussed so far has mentioned a “blue phase”, so this is something I can look in to in the future.
As someone who seems to know much more about TDD, perhaps you can use this post to try understand how TDD comes across to an outsider. Is it easily understood and seen positively? If not, why not?
I hope that helps.
Thanks,
Cassandra
TDD is a coding discipline. It has little to do with testing as you know it — that is, testing as a discipline in its own right. There are three steps: fail, pass, refactor. The big thing it enables is the third step: the ability to change the code. The design of the code can be changed in small and big ways, as long as the tests pass. For more, see my post What’s the Most Important Benefit of TDD?
A skillful, creative tester is gold! Don’t let anyone tell you that TDD will replace testers.
Hi Jon,
Thanks for commenting and sharing the article, its a good read and brings me a step closer to understanding TDD.
Ha, thanks. It does worry me a little that there seems to be the thought that you can cut costs by cutting testers, and the product won’t suffer. Definitely agree with you that testing requires skill and creativity. But even on a basic level, it requires understanding of the product and its intended purpose. If a developer has misunderstood what a feature is supposed to do or deliver to users, it could pass technical tests but fail human ones. From my own experience, I think testers are more likely to use the product as a whole and understand user perspective.
But as I said, it depends on every product, organisation, and team. I find that every situation has different challenges and solutions =]
Cassandra
TDD is exploratory programming. How good the tests (and the design of the code in the long term) end up being depends a lot on the skills of the person doing it. Just like with exploratory testing.
We should do a TDD kata together to give you a taste. Or, find a local craftmanship community event and join them in doing one.
Hi Maaret, thanks for your comment. Yes, that sounds like a good idea and opportunity to experience a bit of it for myself =] Still being so new to the technology industry, there’s certainly a lot for me to learn and explore.
Cassandra