Nerdy Lifestyle Changes: Test-Driven Development
Another installment in my Nerdy Lifestyle Changes series, which essentially details my discovery of awesome nerdy things everybody else already knows about, but I missed because I have to this point by-and-large avoided speaking to other C.S. majors: test-driven-development. Everyone’s doing it, I might as well to!
When I was visiting some of the companies I was considering interning at this summer, I noticed one thing a lot of them had in common: a focus on unit-testing.
Unit-testing was generally something teachers encouraged in my classes to this point, but to me, that always meant writing a piece of code, and then maybe playing with some of the features in some random class with a main method, to see if they would do what you expect. My unit tests were generally thought up on-the-fly as I added features and then deleted immediately afterwards. This meant that if I made any changes, I would have to go back and rethink my testing. Most of the time, I wouldn’t even notice bugs until much later.
In general however, I didn’t do it at all. I would write an entire code-base, and then do some top-down testing at the end. The projects in class were usually small enough to allow this to happen, and my code architecture was generally separated enough that bugs were easy to locate.
But now that I’m playing with TDD, I can’t even begin to understand how silly I was being.
I finally discovered jUnit, which makes unit testing a real breeze. We used jUnit on one project sophomore year, but the context was that the teacher provided several test cases to determine whether or not our code was correct, and no real explanation to how it worked was provided. I was intrigued, but not enough to look into it further.
But now I’m using it heavily. I can simply set up a whole slew of tests for each and every feature of a class, and then rerun the tests every time I make any changes. If I’ve introduced any new bugs by the change, I’ll know right away.
As a result, I’m experiencing unbelievable changes in the way I write my code. I’m now more confident to make huge changes to the implementation of some feature and I’m way more confident that my code actually does what I want it to. Already, I’ve been able to catch an alarming number of mistakes I would have probably otherwise overlooked until it was too late!
I mentioned a while ago, with regards to testing, that I now have my eclipse set up with two code views. One code view I reserve specifically for test code. The amount of test code I write is now actually on a par with the amount of application code I write. For instance, last week, I wrote 5855 total lines of code (a significant amount of this was documentation, to be fair). Of that code, 2319 lines were strictly for testing.
*Aside: I discovered the following linux terminal code to count the number of lines of code in a directory… I know measuring progress on a codebase in lines of code is like measuring progress on a plane by tonnage, but it’s sometimes useful:
wc -l `find /dir/name -type f`
While at first glance, and the reason I’ve always been so resistant to TDD, this seems like twice the amount of work, it actually felt like a lot less work, because every time I made a change, I would get immediate feedback on what bugs were introduced. not only does it improve code correctness, but it also seems to have an effect on workflow efficiency.
But more than anything, it’s all about confidence… and I really dig anything that boosts my confidence.