It’s been a bit more than a few days since my last post. I have a couple excuses. My main excuse is because I didn’t really feel like writing about TDD for days and days. That’s pretty much all I’ve been doing this week – TDD, TDD and more TDD. TDD is not exactly the most exciting thing in the world. My other excuse is thatI’ve been a little preoccupied with the beginnings of my job search. I’ve started to expand my network on linkedin and have been applying for every relevant position I can find in Chicago. I’ve gotten a few phone interviews so far, but I’ve been telling everyone I’m not available until I graduate from the Dojo so it seems like they’re in no hurry to set up any technical interviews. I know everyone says the technical interviews are the hardest and most nerve-wracking part of the job search, but I’m really looking forward to my first one.
Anyways, I said I’d write a post about TDD, so let’s get this party started. First of all, TDD stands for Test-Driven Development, which is a development process that involves a lot of, you guessed it, tests. Basically the gist of it is that you formulate tests for code you want to write before you write it. Of course these tests will fail at first because you haven’t written the code you’re trying to test yet, but then you make the tests pass by writing said code. As you progress along, writing tests that fail, then writing code to make them pass, the idea is that any new code you write should continue to allow all the previous tests to pass. This brings me to the main “pro” of TDD – it does a good job ensuring that nobody accidentally breaks anything.
Imagine working at a huge company like Microsoft. They’ve got thousands of people putting together code for all sorts of projects. It would be pretty easy for one of those thousands of people to change or misuse some little chunk of the codebase and cause problems in other people’s code that might not be immediately apparent. The last thing Microsoft wants is for customers to start calling up and asking why X feature isn’t working anymore. Luckily, TDD can prevent this kind of situation. All those tests that were written for a given products whole set of features will still be around, and in order for any random employee to avoid breaking anything, all they need to do is make sure that all the old tests still pass before they commit their changes. With proper TDD, there is little chance of changes to a project messing up pre-existing functionality.
Another pro of TDD is that by writing tests first instead of code first, the developer is forced to understand the code they’re planning to write more thoroughly. In order to write a test for some code, one must have in mind a clear picture of what the code is actually going to do. If not, how could they write a test for the correct outcome? As you can imagine, if the developer knows very well ahead of time what the code they’re writing a test for is supposed to do, then their job is easy. TDD is great for scenarios where the end product is well understood. However, when there isn’t a clear picture ahead of time of what the final implementation should look/act like, TDD may actually be disadvantageous.
The main “con” of Test-Driven Development is that it’s SLOW. I’ve been experiencing this first-hand at the Dojo this past week. After building a bunch of apps without TDD, and then building some of the same apps with TDD, I am painfully aware of this downside. Taking the time to write efficient tests for every functionality or feature my assignments should have before writing any code feels like a huge time suck when it comes to actually making the site work. Sure, now I know that my site REALLY works, and I have a bunch of documentation to back it up, but it’s hard to miss the defects that my tests would catch on small project whether I write them or not. For example, just to give a comparison for speed of development, back in Django I built the Dojo Secrets app in less than a day. Now, in the current Rails II (with advanced TDD) section, I’ve been working on building the same Dojo Secrets site with TDD, but I’ve already put in about three days and I’m only at the 71% completion mark. I should be able to finish it up tomorrow, and sure I might have been dragging my feet a bit along the way because of how boring tests are, but that’s still 3-4x as many hours spent building with TDD vs without.
I can see the good in TDD, but it’s hard to justify using it on projects as small as my assignments here at Coding Dojo. I don’t think the benefits of TDD outweigh the extra time cost until a project is fairly large and has more than a few people working on it. That being said, I’m glad I have TDD in my toolkit, as I’ll probably have to use it in the future.
Welp, this was an introductory look at TDD. In a later post I’ll get down and dirty into the details of RSpec, Capybara and Factory Girl (gems for testing, yeah I know, weird names eh?), but until then, feel free to check out my repo for TDD Dojo Secrets on github. All the tests for it live in the /spec folder if you want to see TDD in action. Hopefully it won’t be another whole week before I get another post up here!