Why programmers should not kill people.
Tags: Test Driven Development, Clean Code, Software Development

What is the difference between a developer and a doctor?

It seems absurd to even ask this question. Obviously, a doctor treats patients, cures illnesses, saves lives; a doctor through inaction or malice could kill a person. This is why they go through 10–15 years of training and take the Hippocratic oath. A developer just creates computer games and mobile apps.

Except, perhaps, developers who write the code for the pacemakers. And maybe the ones who program the firmware on all those ventilators keeping COVID-19 patients alive (along with every other piece of digital hospital equipment). Possibly the ones developing the control system that keeps the airplanes in the air. Probably those who write code for all the machinery for the nuclear power stations. And maybe the ones who program car controls. Did they save a life? Can they through inaction or malice kill a person?

The question should really be: how many people can one doctor save or kill, and how many - one developer?

How many lines of code stand between you and your own death? When you hit the brake pedal in your car, multiple functions are guaranteed to execute before the control module decides squeeze the callipers to press the brake pads against the discs. How do you know that the developer who wrote those functions was trained properly? Is it possible, they just copy/pasted that code from some YouTube tutorial without looking twice? Is it possible that the entire extent of their training was a four-day Python bootcamp? You often get lulled into a sense of security by all the pretty lights on your car’s dashboard and shiny buttons in the cockpit of an airplane, but make no mistake — thousands of lines of code decide whether you will live to see another day.

As a developer, it’s tempting to hide behind the keyboard and push the responsibility for someone’s life on to the QA, or maybe the product manager, or, possibly the integration team, or even the assembly line. Especially if I have an overzealous boss trying to impress his boss with an early deadline.

That’s not good enough. It will take one developer making one mistake to cause hundreds, possibly thousands of deaths. When we’re in a court room giving a testimony under oath and the prosecutor asks, “how did the system failure lead to this? did it ever work properly?”, we need to have a better answer than “but my boss told me to ship it”.

Can we do anything about it? Well, yes, this would be a pretty sad rant otherwise. We start simple — with testing the code. The question then becomes, what should we test? That’s easy — only the parts of the application that we want to work. How about things that are hard to test? But we made them that way, so let’s fix them. Let’s go the TDD route — write a small test for a small behaviour that already exists and re-implement it. Then remove that behaviour from the existing untestable code. Take that knob and dial it up to eleven: refactor the whole system piece by piece to be completely testable with 100% coverage. Now if anyone asks “how do you know it works?” our answer will be “look at this green bar”.

But TDD is not the panacea either. Poorly written tests are arguably worse than no tests at all: they waste developer’s time and give a false sense of security. Plus if I’m writing tests and code that nobody else can read, I have failed as a software developer. Good tests tell me that the code works, not that the code is good. The next logical step becomes cleaning the code. And since now we have the safety net of tests, we can boldly go where no man… basically it’s easy.

Do you ever get this mental fog when reading another developer’s code? Refactor yours to clear that fog for everyone else. If your code is easy to read, it’ll be easy to extend, it’ll be easy to see any logic issues, and more importantly, it’ll be a good example for others to do the same. Don’t stop there though, keep going until you’ve reached the impossible — your entire application is modular, testable and clean. Of course this is an unachievable goal, but it should give you a thirst for perfection. Improve with every chance you can. If you wrote an app, a class or a function that makes you proud, get another developer excited about it. Have them write a function that’s just as beautiful. Imagine a world, where to add a new feature to an existing system, you just go and write that feature, drop it in, everything compiles, you don’t have to dig through 42 other modules and rearrange 73 functions just to squeeze in your new shiny code.

But what about deadlines? Yes, “What about the children?! Think of the children!!” If a manager says that you can’t afford to spend time on tests because of a deadline, you have the power to say “no, I can’t deploy untested code”. It may make them upset, it may get you in trouble, it may even get you fired. But know this, if you get fired, you’re better off now. It was only a matter of time anyway: you were working for a company that cares about its bottom line much more than about its employees or its customers. That company is not going to succeed. Now you can find a better position. Would a hospital administrator come to a surgeon and say “we set a goal of 2 hours per liver transplant, it’ll make us millions”? Don’t be the surgeon who says “sure!”

Until everyone treats software development as a profession, a discipline, we will always run a risk of a fatal car accident or a plane crash from bad code. It will take time, training and frustration, but with small changes we will get there. That small change starts with you. You are the only one who can decide to hold yourself to a higher standard than your colleagues or your manager. So take the first step to a better tomorrow, write a test.

Inspired by: Robert C. Martin (Uncle Bob) and Simon Sinek