I’ve been working on an automation related project for the last couple of days. As the first stage in the process, I quickly threw together some code to figure out if the idea I had would even be feasible. Once I had proved the concept and had a pretty good idea that it was something I could do without too much work (and hence would probably have a worthwhile payoff), I started to clean it up and put into a maintainable structure. This meant adding unit tests. The exercise of doing this has re-opened my eyes to the power of unit testing.
I haven’t been writing a lot of code lately, but I had noticed in the past that writing unit tests changed the way I wrote my code. It magically became more modular and better encapsulated and different in so many ways. It had to so that I could actually run unit tests against it. However, today I was struck by a few other insights in the value of using unit tests.
One of the first things I noticed was how many bugs can be found by unit testing. I had used the original proof of concept code in a few different ‘black box’ scenarios to see that it could do what I needed it to, but once I start putting tests around it I immediately started finding bugs. The first test I added revealed a bug with inconsistent data types I was using. The very first test. Talk about return on investment. A couple of tests later I found a bug where I was inadvertently overwriting some of my data. This same pattern continued and just by adding some tests to the existing code I found and fixed several more bugs. These bugs probably would have been found eventually, but it would have taken a lot more time than the 1/2 hour or so of work that I put in to these.
I also quickly realized how much easier it was to debug those failures and figure out what was going wrong. When I was working on the code without having unit tests in place it had consistently taken me a lot longer to track down bugs, simply because it would take me longer to run each experiment. If I suspected that something was wrong in module X I might put a print in there and then run the code to see what happened. When I had the code unit tested that would take a fraction of second and so I could quickly find out if my hunch about the problem was correct. On the non unit tested code it would take much long to see if I was right or not. I also noticed that once I had written a unit test I felt an almost physical desire to kick it off and see what would happen. It was like getting that immediate feedback was giving me a dopamine kick and I needed to have more of it. That quick feedback loop made finding and fixing problems much easier (almost fun you might say). There is nothing more frustrating than not being able to figure out why your code doesn’t work. Unit tests help take away much of that frustration
Trust your tests
I was trying to learn some new unit testing tricks related to stubs and mocks and so twice today I thought I had done something wrong in my test only to realize, that no, my test was actually pointing to an error in the code. Don’t trust tests implicitly of course as they are written by humans and as we all know to err is human, but don’t forget that your code is written by humans as well (in my case by the same human). Often the problem is indeed a bug in the code. As I learned today, your code might have a lot more bugs in it than you think it does. I knew my original code was put together pretty quickly and probably had a few minor issues, but I was quite surprised by how many problems I found while adding unit tests.
The moral of the story
Unit tests are awesome. Do more unit testing if you can or push for it’s use if you aren’t in a position or technical skill level to add them yourself. My experience in the last couple of days has once again reminded me of the power and usefulness of this testing tool.
Don’t only do unit testing.