Jonathan Rasmusson wrote “It’s not about the unit tests”. I agree. It’s not about unit tests. It’s about skill and understanding.
Wrestling the code to the ground
I can program perfectly well going mano a mano, me and the code, winner takes all. I’m sure you can, as well. It’s often fun and we get a certain gritty pleasure from knowing that we’ve grappled with the beast and won.
And there’s the trap: when we finally bend the computer to our will and ship the code, we feel that we won. We succeeded. We feel proud.
And honestly, we should feel proud. Every time we ship the software, we’re ahead of all the people who don’t.
In the light of that success, especially when we really had to fight for it, it’s hard to imagine that there could be a better way.
The mark of the professional – of the craftsman – is looking always for a better way.
Of course I work without tests
I can absolutely identify with what Jonathan says. Even now, I often work without unit tests, especially in situations where the program is largely visual. Here are some situations where I often work without tests:
- In Codea Lua on the iPad, what you’re doing is moving sprites around and the like. What Rasmussen’s article does not say, but that I believe to be true, is that it’s quite difficult to write a unit test that tests things like that, because the software “just does” them and you’d normally not say “move this thing by <3,5> and then see if it is at <73,75>”.
- In Second Life, I mostly use scripts to move objects around: rotating clock hands or propellers or such. Here again, you’d not naturally do the math to test whether adding 5 degrees to the hour hand moves it 5 degrees because it just does.
- Updating my web site, I find little value in asking where on the screen something is: I can see on the screen where it is. I am concerned with look, not with pixels. (In some web situations, one is concerned with pixels, and in that case tests might help.)
Now, I pay close attention to what happens when I program, with and without unit tests. So I am quick to notice when I get into a debugging situation, and when I’m modifying the program in such a way as to put existing code at risk of no longer working. So I notice quickly situations where I would likely do better with testing.
Testing can be hard
However, neither Codea nor SL have good affordances for unit testing. I’ve even written testing affordances for both, and have used them from time to time, and it’s still not easy.
For my web stuff, I’ve learned how to use RSpec, and already know the Ruby unit testing framework. But trying to test inside Jekyll and Liquid is quite difficult. You don’t know the framework code well enough to write tests for it. Besides, the point of the framework is so that you don’t have to look inside it.
In all three of those situations, there was a substantial investment of time to learn how to test as effectively as possible. I made that investment because before I decide not to test, I want to be sure testing isn’t so bloody hard as to push me into an inferior way of working. I do that because I have long experience in situations where unit testing does help, and long experience thinking “Oh $#!@, I should have tested this”.
Often I then think “… but it’s too hard”. Commonly, what that really means is “I don’t know how to test this”. I don’t like feeling that I don’t know how to do what I need to do.
Testing can be hard, but debugging is hard too, and uses up precious time. I want to be good at testing so that I don’t have to be quite so good at debugging.
Let’s have the tools for the job we do
Most of us probably have the experience of trying to drive or remove a screw using a coin or our fingernail. Often we manage to get the job done, and often we retain the fingernail and get the screw in more or less straight. If we had a screwdriver in our pocket, however, we’d get the job done sooner and cleaner.
My son Mike is a master auto tech. He has about $50,000 worth of tools, and he knows what each one is for, when to use it, how to use it. It’s the same for us.
The objective in learning things like unit testing, acceptance testing, and the like is to put tools in our pocket, and to give us enough experience with them so that we’ll pull them out at the right moment. If we have the tools and understand them, we can make an informed decision about whether to use them. Without that understanding, we can still get the job done and do it well. We’ll still feel justly proud.
Nonetheless, we might well have done better had we had the right tool and known how to use it.
I don’t do this because I’m disciplined. I do it because it’s fun.
I believe that there’s always a better way to have done something than the way I just did it. So I try to invest a bit in discovering and learning different ways. I invest in tools. I invest in learning.
It’s not about the unit tests
When I’m helping someone learn a practice like unit testing, I’m not trying to get them to have unit tests. I don’t care whether they have unit tests. I’m trying to equip them to have unit tests when they’re helpful.
I have these objectives:
- Show them how I use the practice;
- Describe to them how it helps me;
- Give them enough experience to use the practice well;
- Trust them to decide thereafter when to use it.
It turns out, of course, that the better we are at using the practice, the better decisions we can make about whether it’s helpful. Learning the practice takes time, and time is precious. Having the practice to hand can save time, and time is precious.
It’s not about the unit tests. It’s about knowing when tests are needed, and having the skill at our fingertips to do what’s needed.