Sam Gentle.com

A life undertested

In software it's quite common to do automatic testing of code. Of course, you already do a certain degree of implicit testing as you write the code anyway; you mess around with different parts of the program as you build them, change things to see what works better, and generally put things through their paces. In most cases, the significant functionality will have been hit hundreds of times during development, so why bother to do automated testing?

The problem is that kind of testing only covers the obvious. Maybe you never thought to start clicking things before the page has finished loading, or you didn't try it on an old laptop or a bad internet connection, or even just never realised that some option that you never really use broke while you weren't looking. The problem is that the extremes and edge cases are where most of the bugs show up, and they're also the situations you're least likely to encounter. This is particularly true because you made the system in the first place, so chances are you won't write bugs that are obvious to you.

So we test. We test with random data, we test with random junk that doesn't even resemble data. We test with slow computers, artificially bad internet connections, weird browser/operating system combinations and odd screen sizes. We simulate unplugging random cables, maliciously large floods of web traffic, and random parts of the system crashing. Not always all of these, of course, but every one is a legitimate and useful kind of testing. The common factor is the extreme: in all cases, we want to push our code to the breaking point. We either want to see that it won't break, or we want to know what it takes to break it and what happens when it does.

But there's no reason this attitude has to be unique to software. Any system that is designed by people has similar flaws. We forget to consider certain possibilities, make inadvertent assumptions, or fail to realise when or how our ideas break down. As you go through life, you build up layer upon layer of these systems. You have a system for getting to work in the morning, a system for keeping your clothes clean, a system for thinking about immigration, a system for dealing with stress. Every one of these is tested by just being used in every day life, but not very well. Could we do better?

I think so. Although automated tests may not be feasible, we can still apply that spirit of pushing the extremes. For example, children are a substantial test for the getting to work in the morning system, though there are probably better reasons to have a baby. Someone with children will almost certainly have a better, more robust system than mine. Your system for thinking about immigration would become substantially more robust if you spent time as an immigrant in another country, or if you spent time talking with immigrants in your country. And your stress-handling system is only as good as the most stress it's been able to handle.

In general, it makes sense to avoid unnecessary difficulty. Why make your life harder than it has to be? But this is one argument for seeking out more difficulty. The more you can do so under controlled conditions, the better-tested your systems will be. That might have immediate beneficial consequences if it reveals a flaw in something you took for granted. However, the real benefit comes later, when you hit a difficult situation under less controlled circumstances. At that point you'll be glad to have a well-tested system behind you.