When I was a physicist (before I joined the computer industry), one of my favorite things was running lab experiments. For a physicist, a simple experiment could prove (or disprove) something really deep. The experiment itself would usually be something as simple as rolling two balls – one heavy – one light – down an inclined plane – to see which one reached first (they both reach at the same time). But the underlying concepts that are revealed belie the simplicity of the experiment. They point to a deep realization about the equivalence of gravitational mass (the mass ‘m’ that appears in and inertial mass (the mass that appears in Newton’s second law ). There is no reason these have to be the same – it just turns out that they are.
When I started building software applications, a lot of times, I would write code for days on end without seeing the end result. However, with the advent of unit testing, I have re-discovered the experimenter in me once again.
A unit test is nothing but a small, controlled experiment.
You have a hypothesis, you write a test to prove the hypothesis. It either passes or fails (usually fails on the first attempt!). So – you try and figure out why it failed. And that calls into scope all your skills as a software developer. You often have to re-evaluate the piece of code your were testing – and (usually) rework a part of it. Then you go back – and re-run the test – this time, with a little more optimism. And you keep repeating the process above until your little, (no more than two-three lines of code) test – passes.
In other words, it is no different from performing a scientific experiment. And like the experiment, what the test reveals about your codebase, is anything but ordinary. Often times, unit tests reveal big, gaping holes in the original requirements. Things that fell through the cracks. Things that no one thought about. Things that would otherwise, have only been caught post deployment. It’s never too late to thank your unit tests for saving your application from a catastrophic post-deployment failure.
Unit Testing, is in my opinion, one of the greatest advances in software engineering in the last two decades. Yes – there was a form of testing in the olden days (C code would be tested through drivers that drove the code) – but never were the tools as sophisticated and advanced as today. In my world of .NET development, one is spoiled for choice when it comes to testing tools (MSTest, NUnit and MBUnit and NCover are some of my favorites). Agile is the rage of software development today. However, teams that are doing Agile – but not writing unit tests – might as well abandon the rest of their agile practices. The agility in Agile comes from unit tests – as I tried to describe in an earlier post. In addition to code resilience, unit tests bring a level of excitement (via immediate feedback) back into the software development process. Your thoughts, experiences?