Your Five Step Debugging Guide: Part 3

This week, we're working through the 5-step debugging script, detailing one step each day:

  1. Ensure you can clearly articulate the symptoms of the defect and reliably reproduce it
  2. Define the boundaries in your code within which the defect could exist
  3. Form a hypothesis about the cause (You are here)
  4. Test hypothesis
  5. Begin again at Step 1 until you can demonstrate unambiguously that the defect has been resolved

Today, we're on step 3.

3. Form a hypothesis about the cause of the defect

Ok, so you can clearly articulate and reproduce the issue, and you've made a few passes narrowing down the boundaries within which the defect exists. If you're lucky, you've localized the issue so tightly that the cause is now obvious. This is the time to remain vigilant! Assumptions are the enemy!

Even if you see the issue clear as day right in front of you, you want to approach cautiously. Instead of fixing it right away, form a testable hypothesis about the cause. Keep some emotional distance from your solution, and phrase it to yourself as a possibility. Instead of saying "Oh, I see... There, I fixed it!", say instead "I think X is the problem. If that's the case the when I do Y, I should see Z". This helps you in a couple of ways.

First is emotional. By phrasing as a possibility instead of a certainty, you are keeping yourself open to the occasion that your proposed fix doesn't actually work. A frustrated mind will prevent you from debugging effectively, so it's best to keep from getting emotionally attached to your solutions.

Also, by phrasing as a question and describing the success mode ahead of time, you are much less likely to forget to test your solution. It's not uncommon to be so certain of a fix that you just make a change and move on without checking that it worked. Or, your fix may work in only certain circumstances, but will fail in others. By planning ahead, you can also plan out how to test your proposed solution thoroughly.

Let's look at a concrete example. Let's say you've isolated an issue to the following function, which takes a value and an array, and returns the number of instances of that value found in the array. The issue you've found is that this function seems to be returning the length of the original array. Look it over and see if you can spot the problem. We'll test your hypothesis tomorrow.


function countValueInCollection(value, collection) {
  const foundValues = collection.filter(v => v = value)
  return collection.length
}

Read Step 4

Next Up:
Your Five Step Debugging Guide: Part 4

Previously:
Your Five Step Debugging Guide: Part 2


Want to impress your boss?

Useful articles delivered to your inbox. Learn to to think about software development like a professional.

Icon