Zen and the Art of Debugging
Reader, if you are like me, a good part of your development time is spent debugging. It can take hours or days, or more. But, like any skill, debugging is something you can improve upon. Here are a few thoughts on how to improve your approach to debugging. It's something we all do and we can all get better at it.
Note: The following techniques are tool-agnostic. They help whether you use Chrome DevTools, Safari Web Inspector, Firebug, command-line node inspector, Visual Studio Code built-in debugger, whatever
Keep These In Mind
-
The Program Will do Only What You Ask it to Do
There is hope, and you will find a solution. In a real development setting, your code may not be the issue, it may be an issue in the library or service dependency. -
There are Almost no Intermittent Issues
"Intermittent" issues can almost always be reproduced consistently using clearly written steps that are carried out precisely. They look intermittent only because the steps are not clear or complete enough, or the steps are not being followed precisely each time the test is run. -
Find the Cause before you Find the Fix
We often start "fixing" an issue before we have even identified a cause, let alone the root cause. Without knowing the cause, a "fix" is not a fix. It's a patch. And it will likely cause more issues than it fixes. -
Make Small Changes, then Test
If you make a lot of changes before you test - you are making it more difficult to isolate the one change, or small set of changes that made the difference. -
Keep a record of what you have tried
To find a issue sometimes you have to know what is not an issue. Make a list so you know what you have changed and how then you can exclude those as possible contributors.
A Test Plan Can be Key
Creating a detailed test plan may take 30 minutes, but debugging can take hours or days a test plan is worth the time. It will force you to think about the problem before jumping in.
-
Is the Issue Specific?
Does it really happen only on the Indonesian site using Edge 17 or on an Android phone set to Malay? Can you reproduce it on the US site using the latest desktop version of the browser? -
Reduce data input
When you are testing the email field in a form, a@b.com probably works the same as fyodor.dostoyevsky@famous-writers.com -
Minimize typing
Turn on browser auto-fill with pre-populated test data. Or copy and paste from a notepad. Just make sure to follow the test steps exactly. -
Use mock data
Is a live service required to debug? Would mock data work?
Once your test plan is set, follow each step exactly. A seemingly trivial inconsistency in a step during user interface debugging can make a behavior look intermittent.
Give Yourself a Break
After that hour, or afternoon stop and take a break. If that doesn't help, call it a day. Go to bed. Don't think about it. You will have a different perspective, more ideas, and perhaps a solution the next day.
Recognize When you Need Assistance
If after that time your still frustrated, walk over to a teammate and debug together.
You Fixed It! Probably?
Don't check in yet. First, confirm that it is really fixed and not a fluke. Run through your entire test plan a few times.
- Remove the fix, confirm it's broken.
- Add the fix back, confirm it's fixed.
- Remove the fix, confirm it's still broken. (Yes, again. You may be surprised.)
- Add the fix back, confirm it's still fixed.
Debugging Tips
Debugging may take a while. It may involve many of rebuilds, file saves, server restarts, browser refreshes, etc. It's tedious. Any time shaved from these actions will shorten iteration time and make it just a little more bearable. Some common time-savers that are easy to overlook follow:
- Are you debugging the right file? In the right workspace? Correct URL?
- Are you using too much mouse and too few keyboard short-cuts?
- Are you using ESLint to catch syntax and other fatal but inconspicuous errors in real-time?
- Has the code been refactored to a good state for easier debugging? E.g., cache variables, little or no duplicate code.
- Do you have a step-by-step plan, as detailed as necessary, to test your code?
- Sit with other developers to debug together. Most of the time, one of you will spot a solution.
- Add an alert. Log something. Does it show up?
- Delete the workspace. Does the page still load?
- Is there an error? Did you read it? The error stack in the browser console or terminal may look long, cryptic, and scary. Many of us tend to ignore it until hours of fruitless debugging have passed. Don't do that. Try to read and understand it right away. It usually provides the exact place of the problem, or at least a hint on where to start. It can save you hours of aimless retries.
- Are you calling a library method correctly?
- Read (or re-read) the doc. Then, read the library code itself.
- If you have an idea, stop wondering whether it will work. Try it. If it doesn't work, that means you can move to the next idea. The beauty of software, as opposed to hardware, is that if something breaks - you simply restart.
- Is the response or input correct? Don't assume the service response or the input to a form or a function is correct or what you expect it to be.
- Most applications will likely use open-sourced modules. In general, these modules, especially the popular ones, are of high quality, but any code can have bugs. If you suspect a library method may be the culprit, check it.
- Start removing code! It's called "Binary Elimination". Isolate the problem by eliminating files or code half at a time. Less code, easier to isolate problems.
- Remove half the files/changes, test
- Remove half of the remaining files/changes, test again
- Continue halving and testing as needed
- Once the problem is fixed, restore the removed code. Test.
- Are you trying the same code change and hoping for a different result? Sorry, it won't
- Do you have unstashed changes?
- Is your set-up the issue? Here is a checklist:
- Confirm your environment
- Confirm your configs
- Confirm your branch. Is it the right branch?
- Did you pull the latest code?
- Do you have unstashed changes?
- Did you install dependencies recently?
- Did you clear your workspace cache or temp folder?
- Confirm your version of node or nvm
- How do you start your server?
- Confirm your URL