We’ve all been there. You’ve spent hours and hours writing the code. It looks fancy. What could possibly go wrong? Well, everything. If you take a close look at your code, and deep down you feel like “well, that’s a bit complicated”, you’d better review your code. Complicated code is hardly clean. Test it. Let’s face it. Bugs are a fact of life. There’s no such thing as bug-free code. You have to learn to deal with it! Here’s the catch; the market desperately needs products that solve problems. And sometimes, it behooves to sacrifice code quality for a quicker time to market delivery. Granted, no one wants a buggy software. Developers know that even a minor error in the code can lead to huge problems along the way. It would be great if someone wrote a software that had the ability to correct itself, or better, self-enhance. While this seems more like a pipe dream, advances in A.I (Artificial Intelligence) can turn this a reality in the coming years. Or decades. Who knows? Until then, we have to deal with bugs in our daily work. First things first, you can have your code reviewed by your peers. You can check for answers over the internet. Google is your best friend. Make no mistake, the internet is no silver bullet for every single challenge you encounter down the road. As the American computer scientist Alan Jay Perlis put it “there are two ways to write error-free programs; only the third one works”. With that being said, there’s no one-size-fits-all solution. If there was one single panacea that would certainly be “test, test, and test”. There are three main approaches to dealing with bugs and building applications: Unit Testing, Test-Driven Development (TDD) and Behavior-Driven development (BDD).
At its core, Unit Testing is the process of testing the smallest parts of a certain application, called units. For example, unit testing helps developers look under the hood. If say, an algorithm doesn’t work the way we want to, we could tweak the function, detect logic bugs and improve the code that comprise that particular function. Granted, unit testing assumes your code is easily testable. Otherwise, you are just going to waste precious time. Unit testing can be performed both automatically and manually. So much for the unit testing part.
Test-Driven Development (TDD) assumes that before writing the code, developers should write unit testing. The mantra is: write the tests first. Here is how the test-driven development cycle works:
You first write an automated test for the code you’re going to write. Then you check the test. If it fails, it means that the code is still not ready.
Then you begin programming. The automated test checks again for any error. If the code passes the test, you can move to cleaning it up, by refactoring. You can repeat the whole cycle until the code is clean. See how time-consuming it is? No one wants to waste time. Test-Driven Development favors micro design over macro design. Plus, it’s difficult to apply in practice. In addition to dealing with million lines of code, programmers need to tinker with the source code. Just remember that the source code was not designed to be tested. Performing TDD would delay the time to market delivery. And no wonder many software companies have written it off!
You need to test your application end to end. That’s where Behavior-Driven Development (BDD) comes into play. Here’s what BDD entails:
You first write a failing acceptance test. Then you write a failing unit test.
You make sure the unit test passes. And then you refactor. Last but not least, you make the acceptance test pass. And, as usual, repeat the whole cycle. These are day-to-day maintenance procedures, necessary to make sure that everything runs as smooth as possible. Keep in mind that there’s no one-size-fits-all method when it comes to dealing with bugs. You could use a bug tracking software. You could use a version control system. Use whatever works best for you. Because at the end of the day, we all want to deliver reliable software applications.
If programming is like sex, then detecting bugs is like trying to defuse an atomic bomb: one little mistake and all hell breaks loose. Ignore at your own risk!