Dani Vainstein & Monika Arora Gautam 2 Topics covered Using Breakpoints. The Debug Viewer. Watch expressions. Variables tab. Command tab. Add to Watch. Stepping Step into. Step over. Step out Running Run from step. Debug from step Run to Step
Dani Vainstein & Monika Arora Gautam 3 Debugging Test Req0009 For this purpose I chose for the demonstration the Req0009 test, because it contains loops. Open the Req0009 test from TESTS\Req0009. Put the cursor on line 17 - Call Initialization(). Insert a breakpoint From menu : Debug Insert/Remove Breakpoint. Hotkey : Press F9 Breakpoint
Dani Vainstein & Monika Arora Gautam 4 Debug Viewer Debug Viewer Pane. Before you start debugging, you should be able to see the debug viewer. Also it is recommended to debug in the "Expert View" tab. To make the debug viewer visible and docking. From menu : View Debug Viewer. From toolbar as shown below.
Dani Vainstein & Monika Arora Gautam 5 Debug Viewer Pane. You Should see the debug Viewer in the bottom of QTP Workspace. To permanently view the debug viewer during debugging just make the pane "docking“.
Dani Vainstein & Monika Arora Gautam 6 Start Debugging Now, that everything is ready, you can just click Run or Press F5. As you press run you will see the following dialog Temporary result option When debugging your scripts, always select "Temporary run results folder..." option. QTP saves history result folders for each run. Since you’re debugging it is not necessary to save the history results of each run. Saving the history of runs, will cost you disk space.
Dani Vainstein & Monika Arora Gautam 7 Start Debugging When the debug starts, the workspace becames disabled. From the left side you can see the current line arrow ( yellow ) The arrow always points the line that is going to be executed. Since we've inserted a breakpoint, the script will pause at line 17, waiting for your next instruction.
Dani Vainstein & Monika Arora Gautam 8 Start Debugging In the variables tab ( Debug Viewer Pane ) we can see the variable msg with value - Empty because it was declared in line 15, but not initialized yet. This is another reason to use Option Explicit statement...
Dani Vainstein & Monika Arora Gautam 9 Stepping – Step Into Line 17 represents a call to a function. The function is in FR.vbs Library file. We want to "see" what happens inside the function, for this we are going to use the "Step into" step. Press F11 or from menu Debug Step into. We are going to see that the yellow arrow is now on line 35. But look again, it’s pointing to line 35 of Sub Initialization in FR.vbs library file. When we "Step Into" a function, we can "drill down" into almost any function. ( Later we'll see why ALMOST )
Dani Vainstein & Monika Arora Gautam 10 Stepping – Step Into If we watch the "Variables" tab in the Debug Viewer Pane we will now see 3 variables ( msg, qtp, envXml ) Those variables belong to the Sub Initialization (). In the Variables tab we’ll ONLY see the relevant variables for the current context ( variables declared inside the function in line 32 ) The msg variable that we see here, is not the same msg variable that we saw earlier in Req0009, these variables are the same name in different scopes ( context ), e.g. two OK buttons in different windows. Context
Dani Vainstein & Monika Arora Gautam 11 Stepping – Step over We're in line 35. Line 35 creates a new "Quicktest.Application" object. CreateObject is a VBScript function. We want to "drill down" into this function too, so we press F11. Oops, we moved to line 36, Remember we said ALMOST every function?; the only functions and subs that we can "drill down" are our own functions. We cannot see VBScript functions, QTP functions or built-in functions. Why? Because they are protected. They don't want anyone to see the implementation of their functions. When we have a step with VBScript or QTP function, pressing F11 ( step into ) is the same as F10 ( Step over )
Dani Vainstein & Monika Arora Gautam 12 Stepping – Step over The variable qtp now has a value QTP programmers know what means, and they also know that it is possible to see all the "Properties" of that object in run-time. But, in QTP it is not possible for some objects. I think that this is a big issue of QTP that users always have the most complaints about; "Why can't we see the object properties?"
Dani Vainstein & Monika Arora Gautam 13 Stepping – Step over Up to version 9.2, this is the situation. Whenever a variable is an object and QTP can't show the contents, it will be displayed as. But, what if we do want to see the properties? We have to know in advance which property you want to see. We have to move to the Watch Tab.
Dani Vainstein & Monika Arora Gautam 14 Add to Watch Select the command qtp.WindowState. Right click and select "Add to Watch"
Dani Vainstein & Monika Arora Gautam 15 Add to Watch Immediately, you will see the "Watch" tab with the selected expression. And you also can type, inside the tab in a new line, a custom expression.
Dani Vainstein & Monika Arora Gautam 16 Stepping – Step Over If you press F10 ( or F11 ) on line 36, QTP will be minimized. This option, as explained before, lets the user watch the AUT instead of QTP. In Windows, sometimes, when the AUT is behind the QTP you will get the error "Object is not visible" First solution is to "Activate" the window every time before accessing it. Second solution is permanently "minimize" the QTP, others will prefer to set the Visible property to false. When debugging, just restore the window again.
Dani Vainstein & Monika Arora Gautam 17 Watching Expression After pressing F10 on line 37 ( Set qtp = Nothing ) we will see the following objects: qtp is still an ' ' but in the watch tab we see that the qtp object is not valid. Nothing statement removes the memory allocation for the object, and releases it. We don't need the watches anymore so now we can point each line and just delete them.
Dani Vainstein & Monika Arora Gautam 18 Stepping – Step out In line 40 you can see how PathFinder.Locate works, watch the value of the envXml variable in "Variables" tab. Continue pressing F10 or F11 until you get to line 48. Now, you are in line 48 and you left about 7-8 lines of steps behind. Now, you want to see envXml getting the correct value, the rest of the code... you don't care. At any point, inside a Function or Sub only you can "Step out“ by pressing [Shift+F11]. The execution will continue to the end, but you don't have to spend time pressing F10 until you reach the end of the function. When the yellow arrow is in line 48, press Shift + F11. Now you have "jumped" back to line 18 of Req0009.
Dani Vainstein & Monika Arora Gautam 19 Stepping – Step Over Continue to press F10 until you rich line 25; InvokeApp is another user define function. Lets say, we don't want to "drill" down this function, we know it already works. So, unlike what we did in Call Initialization () instead of pressing F11, we are now pressing F10.
Dani Vainstein & Monika Arora Gautam 20 Stepping – Step Over You will see the 'Login' dialog activated, and the yellow arrow on line 26. Step-over executed the InvokeApp function, but we did not "drill" down inside the function. Debugging can be a large process, F10 ( Step- over ) just saves us time, that's all.
Dani Vainstein & Monika Arora Gautam 21 Debugging a reusable action Continue to line 32 with "Step-over" steps. In line 32, press F11 ( step –into ) Now, you are inside "busLoginMng [busLogin]" external reusable action, line 17. Add to watch Parameter.Item ( "busCode" ) It's obvious that the value will be "Req0009", we are sending this argument when we call the reusable action.
Dani Vainstein & Monika Arora Gautam 22 Debugging a reusable action Pressing F10 on this line will take you to line 95. Reason for this "jump" to 95 is Select Case statement. Select Case "jumps" automatically to the matching Case value.
Dani Vainstein & Monika Arora Gautam 23 Debugging a reusable action That's the reason why we use Case Else. If for some reason there is no a “match”, the script will continue, and we may not know why nothing was executed. Case Else is the statement that executed when nothing matches, we have to write it manually. Usually we recommend to add a warning message with the argument value.
Dani Vainstein & Monika Arora Gautam 24 Using a Command Keep debugging ( F10 ) until you reach line 98; just a line after starting the loop; you should see in the "Variables" tab i = 0. The loop simulates a user typing a string with 0 ( 2 * i ), 2, 4 and 6 characters. Each loop will type a different length of string. Let's say this loop is 0 to 10000, and we want to debug only the 9000 iteration, because we have an error on this specific loop value. So, what we'll do? Press F10 until i=9000? Yes, you can do that...call me tomorrow when you finish. You probably read the title of this slide...yes you are right, we are going to use a “command”.
Dani Vainstein & Monika Arora Gautam 25 Using a Command I exaggerated on purpose, because I want you understand that we have a solution for the 10000 iterations. We return to our script, and i just want to debug the case when i=3. Move to the "Command" tab and type "i=3" and press enter. And move to variables tab.
Dani Vainstein & Monika Arora Gautam 26 Using a Command The command tab allow us to change values during run-time, and test a function/sub/code with a specific case. But, not only that. In the command tab type Print GDictionary( "AGENT_NAME" ) and see what happens.
Dani Vainstein & Monika Arora Gautam 27 Watching Complex Expressions. We are now in line 98. Press another F10 step. We want to "watch" all the keys and items inside the GDictionary object; adding a "watch" to GDictionary will bring you this. Well, we already know that GDictionary is an object !! This is not enough and does not show what we need. GDictionary is a Scripting.Dictionary object. The object has two properties "Keys" and "Items" lets see...
Dani Vainstein & Monika Arora Gautam 28 Watching Complex Expressions. Now, we see that both properties are of type But, see the + signs next the Name column...click on one of them.
Dani Vainstein & Monika Arora Gautam 29 Continue... Line 99 will perform a login, with the wrong password. Press F10 to Step over. Well, you "jumped" to "guiLogin [guiLogin]" reusable action, even though you wanted to step over this reusable action. Sorry, it's QTP, you cannot Step-over on a reusable action. But, also you don't need to "step" all the lines there. Now you're going to see a little trick. In actions combo-box select the action "busLoginMng [busLogin]".
Dani Vainstein & Monika Arora Gautam 30 Run to Step We back to busLoginMng. Disable the breakpoint in line 98 ( Press Ctrl + F9 ). Put the cursor in line 100, just after the call to "guiLogin". And, Select from menu Debug Run to Step or Type Ctrl + F10. In less than a second the yellow arrow paused in line 100. Since we modified “ i ”, then the If statement will be branched.
Dani Vainstein & Monika Arora Gautam 31 PDM.DLL ( Process Debug Manager ) Lately, we discovered that the file PDM.dll version 9, makes “magic” for QTP debugging. One of the most “painful” parts for QTP programmers is that QTP watch doesn’t show us the object methods and properties. PDM.dll version 9, makes the difference. PDM.dll is part of MS-Visual Studio. For more information see : http://www.advancedqtp.com/2008/02/vs2008-debug/ http://www.advancedqtp.com/2008/02/vs2008-debug/
Dani Vainstein & Monika Arora Gautam 32 PDM.DLL Before PDM.DLL After PDM.DLL
Dani Vainstein & Monika Arora Gautam 33 Special Thanks To Tali Hizkia from Israel, Tel-Aviv. Paul Grossman from USA, Chicago. Dalvinder Matharu from USA, San Jose. Mike Manchester from USA, Bolivar. Rajesh Patel from USA, Chicago.
Dani Vainstein & Monika Arora Gautam 34 Make sure to visit us for: Tutorials Articles Projects And much more @ www.AdvancedQTP.com