Avoid the debugger like the pest

In this post I want to explain why I don't like debugging, and prefer instead to use unit testing where I work in tiny sections.
To put this post in context, can first I encourage you to read:

I wait here in the meantime Winking smile

As I said in the other blog post about the debugger not working: The only reason that I see in using the debugger is: inspecting state. Before we look into "inspecting state" we start looking into why and when developers use the debugger.

Bad scenarios for the debugger

image#1 Reading code by stepping through code

image#2 Finding a bug by stepping through code

image#3 Understanding the flow (what happens when and what should happen)

image#4 Discover API


You don't need a debugger to read code! The more readable your code is the even less you are tempted to use the debugger to step through it.
No surprises
Figure: Nice clean code leads to: "No surprises"

You could step through your whole application which might take a couple of hours, or you spend the time in writing a test that verifies your expectation. What is easier? What gives you more advantages for the future, e.g. safety net for future changes?

To understand the flow of your application the debugger might be the 1st option that comes to mind. It might help you understand the flow of your application today, but what about in a weeks time? You probably forgot already about the execution flow of your app.
What about having some tests that describe the execution flow of your application? Maybe a nice combination of unit and integration tests.

#4 Discovering an API with the debugger might be handy. I would MUCH more prefer to have some tests around the API that I could look at, in order to discover the API.



Good scenarios for the debugger

check_thumb[1] Set a breakpoint, run there and inspect the state of your application at that point.

check_thumb[2] On Exception, attach the debugger and see the state

check_thumb[3] Attach the debugger to any running application and inspect the state


Interesting to mention is that even the latter state inspections could be written as tests (maybe even automated for regression).
You are expecting your application variables to be in a certain state, which means Asserts on your variables Winking smile
It's just too much work to write a test for a quick state inspection and that is probably the reason why we don't write tests for those…

Using the Debugger 
Figure: image Bad: Stepping through thousands of lines of code to find why the UI is not showing the right number. (In this case the price in an auction)


Write a test for your expectations on state
Figure: check_thumb[1] Good: Write a test for your expectations on state. Here we expect Anna to be the highest bidder with a price of $91


Rules of thumb

  1. Write better code (readable and understandable)!
  2. Have a tight test harness around your code!

These 2 rules help the reader to understand your code and the flow of your application.
How can we achieve this? Do regular code reviews in your team.



Use the debugger, but think about better investments of your time. Maybe you can write a test for the current scenario that you are trying to debug.

My experience:

  1. Debugging leads to patching until the problem is fixed, but not to understanding the root causes of the problem and fixing it correctly
  2. Debuggers are used to see: Is this line of code actually hit by my code (Manual Code Coverage ;-) )


What do you use the Debugger for?


Anonymous said...

Great advice of when to actually use the debugger. I agree. So much better to have a test that leaves a legacy than one debugging session that is quickly forgotten.

baofish said...

Will keep in mind about it, thanks Peter for pointing me out, will do the Unit TEST as best practice.

Anonymous said...

Try F#
Immutable data --> no state --> no need for a debugger

Post a Comment

Latest Posts

Popular Posts