November 18, 2010

QTP and how to create an autodestruct class

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: