The Five Stages to Unit Testing Enlightenment
The Five Stages to Unit Testing Enlightenment
Join the DZone community and get the full member experience.Join For Free
Disclaimer: This post is meant to entertain and maybe, just maybe, have you reflect on your relationship to software unit testing.
Developers who do not regularly write unit tests, don’t want to start writing unit tests. Probably due to inertia, the natural tendency to resist change. It seems too cumbersome. Once those same developers start writing tests, however, they quickly find, to their surprise, that they are in fact, enjoying it. Who would have thought?
You may also enjoy: Unit Testing: The Good, Bad, and Ugly
There is a kind of gamification quality to unit testing. Seeing that green bar of passed tests tick up to a perfect score of 100% is not unlike the never-ending hunt for loot or experience points of the grinder games that attract so many people. It is, for some reason, appealing to us, to collect those points. Developers get pulled in – they get hooked.
Soon, they find themselves spending more time writing tests. They want — no, they need — that code coverage at a steady 100%. So, they spend entire days on StackOverflow to figure out how to trick their testing framework into believing that the private constructor of their utility class — which in no way, shape, or form, will ever be invoked in production — has, in fact, been covered by tests.
They test all of their code, even the myriad of trivial methods sprinkled across their codebase – they need to test everything, every branch must be covered.
At this point, they are just procrastinating through writing a plenitude of tests. They feel that it’s much easier to write tests than to get started on that next feature that their users need (for which, by the way, the requirements are way too vague, anyway). Just, one – more – line of code – covered…
We as developers are all on this journey towards testing enlightenment, and this is how it goes.
Stage 1: Unit Testing Ignorance
Chances are, that you, in the beginning, can’t be bothered to write tests at all. Sure, you kind of understand the point of them, but it’s just not for you. It’s simply not worth the trouble. You have production code to attend to. The real code, that’s what matters, right? That’s what you are really being evaluated on, right? So why spend time writing irrelevant unit tests? Your test and QA team should pick up any stray bugs later.
At this point, you are a unit test ignorant. Some people stay like this their entire careers. Nothing intrinsic to you can push you along. If everyone around is unit testing ignorant, then that’s how they’ll stay, indefinitely. To advance something or someone, external effort is required. There needs to be something to disrupt the status quo.
Stage 2: Unit Testing Hesitance
At some point, you are forced to start writing unit tests. It might be a manager, a tech lead, a colleague, or possibly your own impression of ever-decreasing self-worth that gets you started. You start writing tests mostly for the sake of writing tests.
If you run into code that you, in a minute or less, can’t figure out how to test, you quietly ignore it. “What the heck is the difference between a mock and a spy, anyway?” you ask yourself. You test your getters and your setters, and that’s about it. You are now qualified for the epithet of unit testing hesitant.
Stage 3: Unit Testing Enthusiast
What happens next is as unimaginable and wonderful to you as it is to everyone around you. All of a sudden, after having written a couple of hundreds of lines of test code, the process — heavens above! — actually starts being pleasant. You realize that it’s not all that bad. You get a warm and fuzzy feeling, deep down in the gut of your programmer-soul, when you see that green bar slowly crawl up to 100% (or is the color of your test suit better described as emerald? Emerald sure sounds more precious, doesn’t it? And precious is just what your test suit is).
All tests pass. Sure, every once in a while, you might need to have that guru on your team describe to you how to capture the parameters passed to your mock. But you are definitely on the right track.
As you start convincing others to write tests, you have now transitioned into being a unit testing enthusiast. Good for you!
Stage 4: Unit Testing Fanatic
Before you know it, you are that guru. You know all there is to know about mocks and fakes, TDD and BDD. Your non-programmer friends think you have become interested in pickling vegetables, like all the other hipsters, because of your constant ramblings about Gherkin. The code you write is absolutely, one-hundred-percent, testable. Dependency injection is second nature to you – and non-negotiable. Your code can effortlessly be injected, stubbed, faked, spied, mocked or what have you. Not a flaky test in sight.
If you can't test it, then no one can.
The tests themselves have become more important to you than anything else. More important to you than your production code and, with that, more important than your users and the business itself. Hours are spent on online forums to find out how to trick your testing framework into giving you full coverage.
You book your managers for a sit-down to tell them about the cost-effectiveness of unit tests, and how it’s of the utmost importance that we never, ever, ever, for any reason whatsoever, allow a single line of code to be committed without it being adequately covered by tests.
You are, at this point, effectively procrastinating by writing tests. Also, what’s worse, you have turned into a testing fanatic.
Stage 5: Unit Testing Pragmatist
Some people make it to the zenith of unit testing, the very last stage of our journey. Mind you, very few make it here because it is easy to get stuck somewhere along the way. Just like AA, the first step towards recovery is to genuinely admit to yourself that you have a problem. Your overambitious testing is the problem. In an extreme case, coworkers tire of a test fanatic’s zealousness and organize an intervention (how awkward!).
Only after realizing the problem can you reach the Zen of testing and become a unit testing pragmatist.
Testing pragmatism, testing enlightenment, reaching unit testing insight, nirvana, what have you. At this point, your testing journey has come full circle, returning to where you started to the notion that delivering features and production code is your main objective.
Unit testing is a mere tool to get features out the door more quickly and with fewer bugs. It is for you to feel reassured that your code does what you believe it should do, not for proving anything to anyone else (and certainly not top-out some, seemingly arbitrary, metric or KPI). Your tests are there to future-proof and to document your solutions.
You test the complex, non-trivial, business-critical code and leave the getters and setters alone. You test integrations and interfaces with third-party code, edge cases, code that might have recently changed, or code that will likely change in the future.
Your bastard private constructors are no longer keeping you awake at night. You lead a more balanced, happy-go-lucky, and more content life as a programmer – to the delight of your co-workers and the satisfaction of your clients and customers.
I am also on this journey, and I find myself somewhere between being an enthusiast and a fanatic. I am working on improving. Oh, boy, am I working on improving. In many ways it’s similar to the Zen Buddhist monks’ search for enlightenment: the harder one tries, the less likely one is to get there.
How far along have you come?
Published at DZone with permission of Said Aspen . See the original article here.
Opinions expressed by DZone contributors are their own.