Monday, March 10, 2008

Why Unit Test?

Recently, I had a down and dirty discussion with a team who is gearing up for a new engagement. This team has been doing Scrum for a while but was struggling with how to fold testing more tightly into their development processes.

The heart of the matter ended up being differences in the purpose and perception of Unit Tests specifically. One camp saw the role of Unit Test as "to find bugs". That's it. They tell you where the bugs are. If they are just about finding bugs, they have more value to new developers than established developers. After all, great developers are much less likely to allow the kind of bugs found by Unit Tests in their code. As a great developer I'm going to catch bad parameters and logic flaws before checking in my code. Integration and functional bugs are probably not going to be found in Unit Tests anyway.

The other camp (read: in my opinion) was resolute that Unit Tests fill a much larger purpose. To my eyes, Units Tests go way beyond just finding bugs. Following are four big ways that Unit Tests can add significant value over and above just finding bugs.

Proving Integration
Today's applications are more distributed and componentized than ever. The number of moving parts has just sky-rocketed with the use of frameworks and new API's, the prevalence of SOA and more component-oriented designs. Personally I see goodness here, but regardless if you like this direction or not, it's happening and is relevant to address. With this fragmentation comes a need to understand when the integration between components is complete. Simple Unit Tests can tell you quickly if the work being delegated downstream of a component is completed and ready. As you are bringing on multiple layers of components the pass rates of the Unit Tests at various layers can quickly show you the level of completeness for the entire integrated system.

Sample Code
One of the difficult parts of delivering a complete software product especially when the product is a framework or an API, if the product is extensible or supports programmability. In these cases specifically, Unit Tests can serve as great examples of how to utilize the API or exercise the programming model. They can often be directly consumed as documentation and sample code for SDKs or in knowledge transfers throughout the life of the product. Building this from outside the team without relying on the author of the component is extremely costly and difficult. However the returns are typically the most valuable.

Proving Design
Designing and building components is easy with the current toolsets. The downside of this is that we can create classes and objects so easily that we don't always think about the bigger picture. Taking time to write code that exercises a new component or interface can act as a sanity check to ensure that the component is easy to use and meets the programmability desires. It's quite often that I see a single API that requires two or three different programming or data interaction models. Some quick Unit Tests would have shown the designer how difficult and inconsistent the usage of the API had become.

Change Management
As a great engineer, it might be totally natural for you to write code that has few bugs. Are the engineers who take up your legacy as experienced? Will the engineer who will open the code in six months to add some features or fix an integration issue be as comfortable knowing how to change things without breaking anything? Would you? Being able to run regressions over time adds a wonderful safety net in the identification of the impact of changes upstream, downstream, or inside your code. It doesn't mean you will (or can) catch everything with Unit Tests but it can sure give you a head start and a level of confidence.

So perhaps this is more about semantics or expectation setting, but I think it helps to keep in mind the variety of purposes Unit Testing can serve. When you expand the contributions made by Unit Tests hopefully you will have an incentive to get even your experienced engineers to spend time writing them.

Tuesday, March 04, 2008

Are You Sure?

It is a pretty normal day for me when a friend says they want to accomplish something and yet they have no idea how to go about it. They want to start a business, but aren't sure what kind of business. They want to make more money, but aren't sure how. They want to get certified/learn new technology/become famous/[insert random goal here]. In all cases, they have an ambiguous idea but not a specific agenda.

A man with a watch knows what time it is. A man with two watches is never sure. -- Segal's Law

In our era of The Paradox of Choice, it is the amazing potential we all have to stand on the shoulders of giants and achieve greatness that is most often our downfall.

We have to choose every day as engineers which technologies to support, which languages to learn, which certifications to pursue. We are bombarded with choices for what social networks to participate in, which email system to rely on, and should we use an Mac or PC? Is it IPhone or Windows Mobile?

As an architect, the most valuable thing you can do is be deliberate in your choices. The hard part is being deliberate quickly. Digesting the massive amounts of ambiguity at a breathtaking pace to synthesize answers and clarity as and when they are needed, usually well before the obvious answers have become apparent. If being an architect was just about picking the obvious when it became obvious, then everyone could do it. (Which probably explains why everyone thinks they can do it.)

If you want to get out there and do something, first narrow down what that something might be. Perhaps start by writing down what it isn't. Then start writing down the attributes or identifying characteristics for what it is. If you can describe what the world looks like when you've achieved your goal, you'll be a good way towards deciding what road will get you there.

Or don't.

It's your choice.