TDD For the Unconverted

Posted 2012-11-16
Written by Matt Frost
Category code

You've heard of Test Driven Development, but you think; "I've got a horrifying monstrosity for a codebase, it's not testable so I can't do TDD". Let me be the first to tell you that you're wrong. I'm not into writing really controversial pieces, castigating people for not doing things a certain way. If you've considered TDD at any point in time, it's because you understand (at least in the theoretical sense) that having predictable software is beneficial. So this is for you, unconverted developer...

omg srsly?!

Looking at old code is not fun, especially if it's old code that you've written. We've all made choices that we'd change, in fact, that's a commonly known sign of growth in a software engineer; so congrats you're growing! "I'm growing, but so are the bug reports, growth is great and all, but how does that help me now?". First of all, you've recognized that spending the majority of your time fixing bugs prevents you from adding new features; hopefully you've also seen that even if you could add features they'd probably put you right back in this same spot in 6 months. So if you're in the loop of releasing a feature, bug fixing that feature for months and doing it all over again; there's something you're not doing right. Fair to say?

building confidence

If you're thinking, "How am I possibly going to test all this code?!" you're thinking about it incorrectly...stopping work to cover your whole application in tests isn't reasonable, nor is it going to yield the type of results you expect. "But I thought testing was good?!" Testing IS good and actually being able to focus on what you're testing is even better. Rather than trying to take years of negligence and magically turn it into a codebase that, if nothing else, lets you predict what's going to happen; start small. Building confidence slowly and as needed is a great way to start building consistency into your application.

confirm your bugs

So here's something funny, we have zero confidence in our application and spend most of our time waiting for the next bug report to come in; yet when it does, we jump right into the code and start trying to fix it. So something that we have zero confidence in, view as inconsistent and aren't able to predict is generating bugs in a way that we feel we're consistently able to predict? I know that's not true and so do you and believe me when I say, this is the best way to start testing. When bug reports come in, we can usually get a general idea of where the bug is living, and from the bug report we know what is happening and hopefully what is supposed to be happening. If we know what is supposed to be happening, we can write a test! Yay! So let's write a test that will pass when the code is doing what we expect it to do, and if it passes right away and you know your test is right...then your bug probably isn't where you thought it was. This helps put a little bit of rhyme and reason to the observation we make when we "fix a bug" and it seems to have shape shifted and moved to another part of the application. Fixing the actual bugs will eliminate the ripple effect those bugs have throughout the system, pretty rad right?

yeah it's rad, but it took a while

Don't look me, you caused this mess in the first place...seriously though, I'm not writing this theoretically. I'm writing this from a position of someone who has voiced all the concerns I'm writing about in here. I've experienced first hand that the idea that writing tests for old crappy code isn't usually valid. "Testing just takes more time, we have to deliver" much time are you spending on fixing bugs? How much time are you spending fixing the same bugs, or fixing symptoms of the same bug? How frustrated are your users/clients getting with the fact that you can't seem to deliver a new feature without having to take "more time" to fix everyone post-release? Ok, if testing takes more time, and you view "damage control" as time well spent...more power to you I guess. I consider extra time to ensure that my code is doing what I think it's doing is worth the extra investment...

but my team doesn't wanna

Yep, make them wanna. Your team not wanting to doesn't mean that you should continue to ignore the problem. Not to completely overwhelm you, but converting people is probably the hardest work of all. If you happen to be on a team that is skeptical, sees it as a time waste or just doesn't care about the quality of their software; that means you have the floor to start writing tests for the things you're working on. Starting small sounds a lot more practical, doesn't it? When historically buggy code starts coming out cleaner and less time is devoted to bug fixing, trust me someone will notice. Think of it as the opposite of git blame, hopefully the other team members start to take notice before the boss does; results communicate more than words. If you work in a hostile environment, or an environment where people don't care; you have to weigh your options. I'm certainly not in the business of giving anyone career advice, if you hate it and you aren't at least need to consider making a change. Being the agent of change in your organization is thankless, until that change completely takes root (this part is theoretical, still working on it); but remember a big part of our job is to do what's in the best interest of our stakeholders. Ultimately, you have to decide whether it's worth it you.





awesome article ! The 'hostile environment' part is a very sad reality.
Experienced it myself many times (although not for tdd but for version control and 'using exceptions in php' or even 'object oriented development').
Fortunately I'm finally 'the boss' when it comes to IT decisions so I'll do my best not to let this happen at our company.

What I want to thank you for is showing me a nice perspective for a person who doesn't yet do unit/functional testing (me), knows it should be done, has no experience whatsoever with it, has no problem making reasonable ammount of time for it but doesn't know where to start. Making tests so that discovered or potential bugs are unlikely to happen is a straightforward way to start. Thanks !



just forgot to add.. I think that a mandatory prerequisite to start unit testing is having a reasonably decoupled object oriented code.

If you have a pile of ugly spaghetti intertwined classess/methods and/or functions you may find that it's impossible to isolate and test the components. Heck, you might even have trouble telling what is a 'component' XD Or whether there 'are' any components, for that matter XD And believe me, at least in Czech republic, this is extremely common.

Functional testing is another thing though. At least with many simple web apps, it should be possible to auto test them with something like silex + goutte, if the url scheming isn't particularily hellish.

That's my opinion anyway.

Post a comment