Olaf Doschke
Programmer
I often refer to the coverage log as a trace log, though by its name it's meant to analyze code coverage, proving/testing, whether all branches of code are covered by test cases of a unit test suite, for example. But it's also a simple log of lines of code executing even profiling execution time, so it's a nice way to discover how code you don't have written yourself but inherited for maintenance works, how it runs.
That's all you need to put somewhere to start recording every single line of code running. Not the code itself, meta data about the code, procedure/class names and line number, for example.
This is how you later can read in all this meta data into a cursor for analysis. VFP itself has an even better tool, the coverage profiler, but it will not give the simple protocoll in the order of code line execution, as the mere data gives, which sometimes is important to find a place in the code doing something wrong, without erroring most probably, giving you no grip on when and from where it is executed. Coverage can reveal triggered calls, like dbc triggers, but also bindevents etc., it doesn't fail to tell you what actually ran, the only lines it won't log are properties set to expressions, unless the expressions call into functions, which appear in the log.
What's missing is a way to put in own lines, like remarks or hints of something you know happens before or after something else, to narrow down the interesting part of the log. You can always end one log and start a specifically named log, but it will become tedious to later have to analyse many short logs. For that problem I had an idea I'll use today:
or even
This will show up in the log this way:
[pre] 0.000071,,0000j18p00b3,1,c:\users\...\appdata\local\temp\0000j18p00b3.fxp,2
0.000022,,[highlight #FCE94F]hint[/highlight],3,c:\users\...\appdata\local\temp\0000j18p00b3.fxp,3[/pre]
Execscripts generates a temp prg file, compiles and runs the fxp with a cryptic name, but what is most important, you find your hint keyword within the logs meta data, so you can smuggle your own keywords into the log and mark places of interest, places to make a cut. This way you can have a single longer coverage.log and still find sections of interest in it, especially, if you look for several sections and even won't know how to get there without an experienced user of the software you try to analyse. With the messagebox variant you can also see whether code runs before or after certain other events and remember visually what happend before and after a certain message was shown. Instead of "hint" you can have anything here, just the procedure name has to be a valid procedure name. And though that doesn't allow you to log anything into the coverage log, it even could contain data, as long as you assemble a valid procedure name, ie for numeric output prefix it with an underline, and it becomes a valid procedure name, in general:
The main idea here is to generate procedure names on the fly, as they will be put into the coverage log. The procedure has to be called and has to have one line of code at least, eg just the return, to appear in the log with its name.
Bye, Olaf.
Code:
SET COVERAGE TO coverage.log
Code:
Create Cursor curCoverage (bExecTime B, cClass C(128), cMethod C(128), iLine I, cFile C(254), iStacklevel I)
Set Point To '.'
Append From coverage.log Type CSV
This is how you later can read in all this meta data into a cursor for analysis. VFP itself has an even better tool, the coverage profiler, but it will not give the simple protocoll in the order of code line execution, as the mere data gives, which sometimes is important to find a place in the code doing something wrong, without erroring most probably, giving you no grip on when and from where it is executed. Coverage can reveal triggered calls, like dbc triggers, but also bindevents etc., it doesn't fail to tell you what actually ran, the only lines it won't log are properties set to expressions, unless the expressions call into functions, which appear in the log.
What's missing is a way to put in own lines, like remarks or hints of something you know happens before or after something else, to narrow down the interesting part of the log. You can always end one log and start a specifically named log, but it will become tedious to later have to analyse many short logs. For that problem I had an idea I'll use today:
Code:
=EXECSCRIPT("[highlight #FCE94F]hint[/highlight]()"+CHR(13)+"Procedure [highlight #FCE94F]hint[/highlight]()"+CHR(13)+"return")
Code:
=EXECSCRIPT("[highlight #FCE94F]hint[/highlight]()"+CHR(13)+"Procedure [highlight #FCE94F]hint[/highlight]()"+CHR(13)+"Messagebox('[highlight #FCE94F]hint[/highlight]')")
This will show up in the log this way:
[pre] 0.000071,,0000j18p00b3,1,c:\users\...\appdata\local\temp\0000j18p00b3.fxp,2
0.000022,,[highlight #FCE94F]hint[/highlight],3,c:\users\...\appdata\local\temp\0000j18p00b3.fxp,3[/pre]
Execscripts generates a temp prg file, compiles and runs the fxp with a cryptic name, but what is most important, you find your hint keyword within the logs meta data, so you can smuggle your own keywords into the log and mark places of interest, places to make a cut. This way you can have a single longer coverage.log and still find sections of interest in it, especially, if you look for several sections and even won't know how to get there without an experienced user of the software you try to analyse. With the messagebox variant you can also see whether code runs before or after certain other events and remember visually what happend before and after a certain message was shown. Instead of "hint" you can have anything here, just the procedure name has to be a valid procedure name. And though that doesn't allow you to log anything into the coverage log, it even could contain data, as long as you assemble a valid procedure name, ie for numeric output prefix it with an underline, and it becomes a valid procedure name, in general:
Code:
=EXECSCRIPT("hint_&cInfo()"+CHR(13)+"Procedure hint_&cInfo()"+CHR(13)+"Messagebox('message for &cInfo')")
The main idea here is to generate procedure names on the fly, as they will be put into the coverage log. The procedure has to be called and has to have one line of code at least, eg just the return, to appear in the log with its name.
Bye, Olaf.