Why is
it so
important to prevent yourself from debugging with your hands?
When you are debugging a program, without realizing it, you think that in one debugging session you will correct all the problems that have arisen as part of this task. But our short-sightedness does not want to believe that in fact there is not one problem, but several. And in one debugging session it will not be possible to solve all these problems.
Therefore, you will need to run this code several times in debug mode, spending debugging hours on the same piece of code. And it's only you who spent so much time on this part of the program. Each team member who is “lucky enough” to work with this code will be forced to live the same story that you have lived.
')
I'm not talking about the fact that people in teams change, teams change and so on. Man-hours go for the same thing. Stop doing it. I'm serious. Take responsibility for others. Help them not to experience the same part of your life.
Problem: Difficult to debug compound code
Possible problem solving algorithm:
- Split into separate parts
- We throw out debugging, we simply prohibit to use the Debug mode.
- We analyze individual parts (we invent non-valid situations for them, boundary cases)
- We write tests for each separate part of the whole algorithm.
- In tests, sometimes you have to recognize intermediate data, but ...
Debugging is more inaccessible to us, therefore we stick Trace into those parts where there is a suspicion of incorrect execution of the algorithm. - By tracing you need to understand the cause of the problem.
- If it is not clear, then most often either it is worthwhile to write another test, or perform a trace one step earlier.
The solution is automated testing using logging. You write tests for all (or almost all) situations that lead to problems. Plus, if there is a need for debugging, then you trace until you understand the problem.
Thus, you save other people from debugging this code, because if a problem arises, the person will look at your logs and understand the reason. Only important sections of the algorithm are logged.
Let's see an example. You know that individually all interface implementations work (because tests are written to prove this). But when interacting all together, incorrect behavior occurs. What you need? You need to log responses from the "correct" interfaces:
void Register(User user) {
This example shows how we trace certain parts of the algorithm in order to be able to fix one or another stage of its execution. Looking at the logs, it becomes clear what is the reason. In real life, this whole algorithm would be worth breaking up into separate methods, but the essence does not change.
All this at times speeds up writing code. You do not need to run through the loop with F10 in order to understand which iteration of the loop the problem occurred. Just log in the state of the objects you need under certain conditions at a certain iteration of the cycle.
In the end, you leave important logs and delete side logs, for example, where you learned the state of the object at a certain iteration of the cycle. Such logs will not help your colleagues, because you, most likely, already understood the problem of an incorrect algorithm and corrected it. If not, keep developing in your thread until you find the reason and fix the problem. But logs that record important results from the execution of other algorithms will be needed by all. Therefore, they should be left.
What if we don't need this garbage? In this case, perform tracing only within the framework of debugging, and then clean up after yourself.
pros | Minuses |
---|
It is possible to trace the execution of the algorithm without debugging. | You have to write the trace code. |
In production, logs will sometimes collect the necessary data. | In production, logs will sometimes collect unnecessary data. |
Debugging time is reduced, because you often run the code and immediately see the results of its execution (all at a glance) | You need to clean up after you. This sometimes leads to re-writing the trace code. |
Colleagues can track the execution of the algorithm by logs | Colleagues have to look not only at the algorithm itself, but also at the trace of its execution. |
Logging is the only way to debug non-deterministic scripts (for example, multithreading or networking) | Production decreases performance due to I / O and CPU operations. |
Finally I would like to say this: think with your head. No need to jump from one extreme to another. Sometimes debugging with your hands really quickly solves the problem here and now. But as soon as you noticed that something quickly, here and now it does not work, it's time to switch to another mode.