Somewhere in our application under test, we have a webpage that only continues loading if the mouse is slightly moved. The page is loading while QTP is syncing the page. During the syncing, I cannot send mouse move commands from QTP to the application.
I don’t know why the application has this feature and “they” don’t want to fix it, so… work around time.
I created a low profile mousemove application in C that only does one thing: After 5 seconds it moves the mouse cursor one pixel to the right. And after 5 seconds it moves the cursor one pixel to the left. Repeat.
Actually it is an cut down version of out nolock.exe application, this application sniffs the mouse cursor movements. If it detects inactivity for 10 minutes, it moves the mouse cursor slightly in the same manner as discussed above. This program has a shortcut in the Windows Startup folder and prevent the screen from locking when automated tests are running.
But back to the autodestruct class. We want to have a “single line of code” to implement this in any function where we expect the screen to hang. This class starts the mouse moving as soon as it is created and stops the mouse moving when it is destroyed.
Private Const MOUSE_MOVE_APPL_NAME = “mouseMover.exe”
Private Const BINARIES_FOLDER = “C:\QTP_Framework\tooling\bin\”
Class cls_AutoDestructMouseMover
Private Sub class_initialize()
‘ Put the cursor somewhere to prevent it is on the extreme right position
call extern.SetCursorPos(100, 150)
‘ Run the external mouse move application
systemutil.Run BINARIES_FOLDER & _
MOUSE_MOVE_APPL_NAME, "", BINARIES_FOLDER
End Sub
Private sub class_terminate()
‘ Kill the mouse move application
systemUtil.CloseProcessByName MOUSE_MOVE_APPL_NAME
End Sub
End Class
And make a public accessor for the class:
Public function [new AutoDestructMouseMover]
Set [new AutoDestructMouseMover] = new cls_AutoDestructMouseMover
End Function
Now, we can implement the class whenever it is needed:
Public Function Example
‘ Create the object, make it move!
Dim autoDestructMouseMover : Set autoDestructMouseMover = [new AutoDestructMouseMover]
Call TimeConsumingFunction
‘ Destroy the object, let it stop!
Set autoDestructMouseMover = Nothing
End Function
But wait, we called it an “autodestruct” class, what about the autodestruct? Well, The last line of code is not necessary. When the Example function ends, it automatically destroys all variables and objectpointers with local scope. We can simply reduce the implementation of the autodestructor to one line of code (I know, I am cheating with the semicolon):
Public Function Example
‘ Create the object, make it move!
Dim autoDestructMouseMover : Set autoDestructMouseMover = [new AutoDestructMouseMover]
Call TimeConsumingFunction
End Function
And the autoDestructMouseMover object is automatically destroyed with the function clean up.
Nice. But are there more appliances for an autodestruct object? Oh, yes.
What do you think an autoDestructStackTracer?
Class cls_AutoDestructStackTracer
Private procedureName_
Public Sub Init(pName)
procedureName_ = pName
Print now & “ ADST Start “ & procedureName_
End Sub
Private sub class_terminate()
Print now & “ ADST Exit “ & procedureName_
End Sub
End Class
And make a public accessor for the class:
Public function [new AutoDestructStackTracer](pName)
Set [new AutoDestructStackTracer] = new cls_AutoDestructStackTracer
[new AutoDestructStackTracer].Init pName
End Function
And let’s test it:
Public Function ExampleParent
Dim autoDestructStackTracer : Set autoDestructStackTracer = [new AutoDestructStackTracer](“ExampleParent”)
Print “I’m with ExampleParent now!”
Call ExampleChild
End Function
Public Function ExampleChild
Dim autoDestructStackTracer : Set autoDestructStackTracer = [new AutoDestructStackTracer](“ExampleChild”)
Print “I’m with ExampleChild now!”
End Function
Call ExampleParent
Output:
18-11-2010 9:06:06 ADST Start ExampleParent
I’m with ExampleParent now!
18-11-2010 9:06:06 ADST Start ExampleChild
I’m with ExampleChild now!
18-11-2010 9:06:06 ADST Exit ExampleChild
18-11-2010 9:06:06 ADST Exit ExampleParent
And consider uses of an [new AutoDestructFunctionTimer](pName) to measure the performance of your different functions. Or a [new ScreenShotOnFunctionExit] (and more generalized: [new ExecuteOnFunctionExit](“call PerformScreenshot”)) when you have lots of functions with multiple exit points.
No comments:
Post a Comment