Before reading the debugging chapter on FCC I had my own way of debugging code. This “method” I developed I figured out by myself through trial and error. Since I’ve never spoken to anyone about it or had any formal training on it, I don’t know if it is a sound approach or if there are better ways so I’d like to share it with the FCC community and ask for your feedback.
So far this method has served me well and I use it to debug PowerShell. However, since learning JS I’ve ran into problems where this method doesn’t work sometimes. I think the issue is not JS per se but the fact that my JS code is using callbacks, and I don’t think this method is well suited to them (PowerShell doesn’t use callbacks).
There are two goals I want to achieve from this post; one - demonstrate this “method” and get your feedback on it. Do other programmers debug like this or is it flawed? Is there a better approach to it? Two, come up with similar method, which works for callbacks. This will make more sense with an example. Imagine the following basic PS script:
get-process –t | out-file c:\temp\file.txt
For those of you that don’t know PowerShell, the get-process
is a command that lists all processes running on the PC and memory allocation etc. The | is known as the pipeline and is used to say you want to pass on the results of get-process
to out-file
. Therefore, this basic command gets a process list and saves it to a file.
Let’s say this errors (the error is irrelevant), here is my “method” to debug it:
-
I can see that there are two commands and that the second command is dependent on the first command running successfully, so I run the first command at PS terminal by itself and see what happens.
-
At the terminal I type get-process –t and press enter and it errors (the code above is wrong on purpose). I look up the command and find I have a syntax error; the –t parameter doesn’t exist and I shouldn’t be using it so I remove it.
-
I now test it again by typing get-process at the terminal and press enter. It works. I now know this part of my script is working so I run the whole command again.
-
At the terminal I type the full fixed up code get-process | out-file c:\temp\file.txt but it still errors. So now my reasoning is that the next issue is with the out-file command.
-
I follow the same troubleshooting steps above on just the out-file c:\temp\file.txt command until I fix it. Let’s say the error was a typo and it now works.
-
Since both commands now work individually, I go back and re-run the original command as a final test and it works.
I am assuming that the above approach is what others use too before loading up a full-blown debugger; when the code is simple and you can easily trace the steps there is no need to perform debugging. Notice I say “I am assuming” as I don’t know any coders I can ask to confirm this, can some please confirm if my assumption is correct? UPDATE ON THIS – I did some researching and came across the concept of Unit Testing so I think I have been doing this without realising, is this correct?
NOTE: For those of you that know PS you may notice that my code above isn’t entirely accurate; I am aware of this and don’t need you to correct me - the point of the example is to show you my debug approach, not fix the code.
Now let’s imagine the code is more complex (but not by much). Let’s say the code has 10 functions. Some of those functions will return their outputs to other functions. Imagine that one function in particular ultimately calls all the other functions through chaining. Now in order to troubleshoot this function, each time I make a change to it I need to call it again, which means it calls all other functions again. This can be tedious and sometimes just one of those 10 functions may take ages to run, ie maybe it downloads a large JSON file. Let’s say I want to bypass this one function that downloads the JSON file to speed up my troubleshooting. What I’ll do instead is run that function and return it’s results to a temp variable. I’ll then pass that variable into wherever the previous function was called. This allows me to continue my troubleshooting without actually calling the time consuming JSON function. Once I finally fix the issue, I then go back, delete the temp variable and revert the code to call the JSON function again. My question is, is this approach normal? do others do it? If not, then what is a better approach?
Now that I’ve explained all the above we are coming to the main reason I raised this post; this method doesn’t work with callback functions. The reason for this (I think) is because they do not return a value like normal functions do; therefore I can’t output the results of the first function to a variable, which I will then later pass on to the callback function to unit test it . So how do I unit test the callback function only if it is expects an argument (from the function that called it) and I can’t give it one? If I was somehow able save the results from the previous function to a variable (like with normal functions), I could test the callback function by itself by passing this variable in as an argument; but since the original function doesn’t support returning a value I can’t do this. Surely this would be a major drawback to debugging callbacks so I’m guessing there is an equivalent way to do this and I just don’t know it yet. Or maybe I am looking at this the wrong way. Any ideas?
I know this is a massive post but please try to answer all my questions as each one of them has been bugging me for some time now.
Thanks,