An Obsession with Everything Else

http://www.derrickschneider.com/atom.xml

Sunday, December 28, 2008

More Unit Testing Revelations

Since I started making unit tests an active part of my development tasks at home and at work, I've noticed a benefit beyond the promise of stability and support for refactoring.

Unit testing has made me a better programmer. More precisely, it has made me practice what I preach about good programming practice.

One well-known best practice in the OO world — and probably in the procedural programming world, too — is to keep chunks of code small, focused, and free of side effects. This is partly for code maintenance purposes: A large method is cumbersome for a new programmer to understand. But this kind of modularity also allows other programmers (or yourself) to more easily subclass a class and add new behavior to suit new needs.

But in the heat of coding a new feature, I don't always take the time to think about the best way to break it apart. I figure I'll fix it in a refactoring pass. Fifteen years as a professional programmer, and you'd think I know that that chance will never come. Bugs need fixing, or the powers-that-be move me on to a new feature.

With unit tests as part of my task, I'm forced to think about testable chunks, and those are usually exactly the level of size and functionality that makes sense from an object-oriented perspective. I find myself thinking about the tests I will write as I code the class, and that in turn forces me to realize that a given method is too big, has too many side effects, or is otherwise not testable. This is especially true because I have made the decision that our team shouldn't write unit tests for retrieving objects from a database, since that is all handled by the well-vetted Hibernate library. When I write a method that retrieves objects from the database and does calculations with them, the "you'll have to test this" part of my mind realizes that I need to move the calculations into their own method (or methods) so that I can test them even without a database connection. In other words, I move specific functionality into its own method, exactly where it belongs.

Over and over again, every time I code with unit tests in mind, I see myself doing more on-the-fly refactoring as I write a feature. I don't wait for the magical refactoring time that never comes: I do it as I go.

0 Comments:

Post a Comment

<< Home