It’s Friday night. after an intense week of work, you’re about to take off to enjoy your week-end. Your boss storms in the office:
“You’re still here! Great, I need you to add a hot fix in our Phronabulax System. We expect a demo Monday morning very early, everything has to be ready!”
Well. That was unexpected. You know your boss, he/she wouldn’t ask if it wasn’t really urgent. You grumble a bit but still go dig into the code to do the work.
30 minutes later, you commit your work and breathe a sigh of relief. Wait! You completely forgot the tests! You didn’t add a new test covering the modification. There might be unintended side effects. What shall you do?
Without a doubt, you shutdown your computer and leave. This can wait Monday, and the fix was trivial!
Are you a bad developer? An impostor? Nope, I certainly hope not. I think you’re just a Human.
What is a Unit Test?
I won’t delve into the details of Unit Testing, TDD (Test Driven Development) or any purely technical aspect. I’d like to scratch what is hidden beneath Unit Tests. More precisely, what it reveals about us, about our Human Nature.
The formal definition of a Unit test by Wikipedia states:
In computer programming, unit testing is a software testing method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures, are tested to determine whether they are fit for use
As any proper formal definition, it’s absolutely opaque for anyone who doesn’t already know what is a Unit Test.
One might ask “What’s the point of the definition then?". To look educated and unreachable my dear!
A Unit Tests is a piece of code that you write that will execute a subset of your real program to verify its behavior.
If I input
5, it should spit
"Hello", If I input
42, it should crash, and so on.
I don’t have the time to write tests
And I agree with you, me neither. Writing tests requires time, the structure of the test is a craft in itself. Having a decent test coverage is a real effort. Still, I have a question for you:
Do you test what you develop?
I mean it in the simplest sense: you write some code, run the program and check if it works as intended. Chances are, you are doing it all the time. You might even yell at your computer because the compilation / startup time to test it takes more than 2,4 seconds.
Unit Tests are merely an automated way of doing what you already do by hand. But I understand, it’s time consuming and the feature has to be delivered yesterday. So why write tests?
Human After All
Because you are just a Human! I believe testing reveals something very interesting about us, as Humans: we’re absolutely fallible, and even more while coding.
Don’t believe me?
What is the quality of you work when you slept 3 hours ? When there’s a disturbing noise in the office? When you neighbor keeps chewing that dreadful, juicy candy?
Let’s assume you always sleep 8 hours each night and that your noise canceling headphones does wonder.
What about that dark corner of the project? The one that makes everyone look at their feet when you need to modify it? It was written ages ago by a dark ninja-shaman on a moonless night? Nobody understands it and even less dares to touch it?
Yes, it makes you cringe every time you approach it.
That’s exactly why Unit Tests exist: because you’re just a Human. You can be tired, angry, not concentrated. Because you don’t have the time nor the energy, the Unit Test will execute the 526 cases that you don’t want to check yet another time.
Down the Rabbit Hole
What I find incredible is not that the discovery that we are deeply flawed. The Atlantic Ocean could be filled with the ink spilled on this topic for the last 3000 years.
What is amazing is our resourcefulness. As soon as we admit that eating every dish of that damn Chinese self-serve buffet turns us into brainless oysters for the rest of the afternoon, we start constructing countermeasures.
Unit Test are for me the product of humble yet very sharp minds, who acknowledge their weakness but still want to get the job done, in the best possible way.
See it that way: we are tool builders. We don’t have claws or big furs, so we build tools to compensate. Writing tests is an answer to our daily stupidity.
The Beatitude Of The Fool
When I started doing tests, I was closer to the attitude of the rebel Teenager than the excited newbie: “Yeaaaah! Whatever. I still ship good code. Meh”.
But, as the test coverage grew, I started to notice an interesting pattern:
- Customer requests feature X
- I implement feature X
- I don’t write any test, feeling confident. The day was sunny, my focus was Zen-like while writing the code
- I ship the feature X
- Customer gets back to me “Thanks Robin! X works great, however Y is broken!"
- I’m sorry what? I dig in, and see the regression
- I (finally) write a test, the test fails. I fix the bug and ship again
Rince and repeat. That feeling, between the “I’m sorry what?" and the understanding that by simply adding a couple of tests, the bug could have been prevented is priceless. It’s a mix of shame and anger.
After a couple of iterations, I systematically wrote a test for any feature. And that my friends, was a pure Dopamine shot.
Now, I see my tests as a handcrafted parachute. I can code and feel the bliss of the Fool. I can be Human, stupid, tired, and my tests have my back. Oh, what a feeling!
Side Effects and Cult
A beautiful side-effect of testing your program, is that it puts you in the shoes of the user of your API. You write an incredibly efficient program, great! How usable it is?
Remember, you don’t have the time to write tests, do you think your colleague will have the time to understand your crazy Logorrhea of functions, variables and convoluted classes? Of course not!
Testing gives you a feedback on how your API feels. This is extremely useful, because you won’t be able to know that before having to modify it again.
However, I want to add a big nuance:
Not everything should be tested
You know how it’s called when someone tells you “If you don’t test X, you’re worthless”? Religion Fever.
In my humble opinion, it’s as stupid to refuse to test anything than to insist on testing absolutely everything.
Some situations makes the tests impossibly hard to write or maintain.
In many cases, I don’t write any UI test. Why? Because I have a limited time, and I honestly care little about UI testing. It makes perfect sense for huge projects, with very strict UI designs.
I see testing more as a state of mind, a humbling affirmation of our imperfection and a celebration of our imagination to face it.
As with any craft, it has to be practiced and repeated. Sometimes your tests will be useless and badly written. Other times it will fit perfectly to your project.
It takes time, but it’s worthwhile. You’ll thank yourself for doing it, trust me.