Having problems with your account or logging in?
A lot of changes are happening in the community right now. Some may affect you. READ MORE HERE

Is there a way to save a screen dump with SilkTest when a TestCase fails?

Is there a way to save a screen dump with SilkTest when a TestCase fails?

The following article deals with how to set up a `screen dump` when a testcase fails. This will allow for a failure to be documented in image form so that an error may be better understood if running tests unattended.

The SilkTest Recovery System

The SilkTest recovery system ensures that your application is in its "base state" before and after every testcase is run. A typical "base state" has these characteristics:

  • The application is running
  • The application is not minimized
  • No application child windows (e.g. dialog boxes, message boxes) are open
  • The application is active (it has focus)

To make this a little clearer, consider the base state for Notepad, the text editor that comes with Microsoft Windows.

  • The application is running - the process notepad.exe is running
  • The application is not minimized - the Notepad window has not been reduced to an icon in the taskbar and is in either maximized (takes up the whole screen) or in a normal (neither minimized nor maximized) state
  • No application child windows are open - no dialog boxes like Open (accessed by choosing Open on the File menu) or Find (accessed by choosing Find on the Edit menu) are open
  • The application is active - any keystrokes you type will cause the typed characters to appear in the Notepad document area

Where the Recovery System Lives

The core recovery system functionality is in the file defaults.inc, located in the SilkTest installation directory. Note that since defaults.inc is a SilkTest "system file", and should never be changed, except in extremely rare situations. The reasoning behind this is that:

  1. The changed defaults.inc would required to every machine that has SilkTest installed.
  2. When SilkTest is upgraded to a newer version or a patch installed, defaults.inc might get overwritten and the changes would then be lost.

The defaults.inc file contains the following functions.

  • DefaultBaseState - the default base state that, as noted above, makes sure the application under test is running, active and not minimized, and that no child windows are open.
  • DefaultTestPlanEnter - runs when a test plan is entered. Does nothing by default.
  • DefaultTestPlanExit - runs when a test plan is exited.
  • DefaultScriptEnter - runs when a script is entered. Does nothing by default.
  • DefaultScriptExit - runs when a script is exited. Logs exceptions to the results file by default if there were any.
  • DefaultTestCaseEnter - runs when a testcase is entered. Sets the application state associated with the testcase by default.
  • DefaultTestCaseExit - runs when a testcase is exited. Logs exceptions to the results file by default if there were any.

The purpose of these functions will become clearer in the next section.

Overriding the Default Recovery System

To override the script enter/exit, testcase enter/exit or test plan enter/exit functions, define a new function that is named the same as the function you are overriding, except remove "Default" from the name. For example, to override DefaultTestPlanEnter, a new function named TestPlanEnter needs to be defined.

Important note: the CARDINAL RULE of overriding any default recovery system function is to retain the functionality in the default function and then build upon it. Except in very rare cases, it should not be necessary to omit what is in the default function and redefine the function "from scratch".

To better illustrate when SilkTest calls the recovery system functions, all of the default recovery system functions will be overridden (except DefaultBaseState) in the following override.inc file.

Copy the default functions, remove "Default" from the function names, and put a Print ("in ") statement at the beginning of each function.
Why? Remember the CARDINAL RULE from above - leave the functionality that was there and build upon it.

[ ] // override.inc
[ ] 
[-] TestPlanEnter ()
      [ ] Print ("in TestPlanEnter")
[ ]
//************************************************
[ ] 
[-] TestPlanExit (BOOLEAN bException)
      [ ] Print ("in TestPlanExit")
[ ] 
[ ] 
//***********************************************
[ ] 
[-] ScriptEnter ()
      [ ] Print ("in ScriptEnter")
[ ] 
[ ] 
//***********************************************
[ ] 
[-] ScriptExit (BOOLEAN bException)
      [ ] Print ("in ScriptExit")
      [ ] 
      [-] if (bException)
            [ ] ExceptLog ()
[ ] 
[ ]
//***********************************************
[ ] 
[-] TestCaseEnter ()
      [ ] Print ("in TestCaseEnter")
      [ ] 
      [ ] SetAppState ()
[ ] 
[ ]
//**********************************************
[ ] 
[-] TestCaseExit (BOOLEAN bException)
      [ ] Print ("in TestCaseExit")
      [ ] 
      [+] if (bException)
            [ ] ExceptLog ()
      [+] else
            [+] do
                  [ ] @"Browser".WaitForReady ()
            [ ] except
      [ ] 
      [ ] SetBaseState ()

Next, create the following script file with two testcases. The testcases don"t do any testing; they are merely meant to help illustrate when the recovery system functions are called.

[ ] use "override.inc"
[ ] 
[-] testcase FirstTestcase ()
      [ ] Print ("in the testcase named FirstTestcase")
[ ] 
[-] testcase SecondTestcase ()
      [ ] Print ("in the testcase named SecondTestcase")
      [ ] 
      [ ] Print (3 / 0) // force an intentional divide-by-zero exception

Running this testcase yields the following results:

[ ] Script override.t - 1 error
[ ] 
[ ] in ScriptEnter
[-] Testcase FirstTestcase - Passed
      [ ] in TestCaseEnter
      [ ] in the testcase named FirstTestcase
      [ ] in TestCaseExit
[-] Testcase SecondTestcase - 1 error
      [ ] in TestCaseEnter
      [ ] in the testcase named SecondTestcase
      [ ] in TestCaseExit
      [ ] *** Error: Divide by zero
      [ ] Occurred in SecondTestcase at override.t(14)
[ ] in ScriptExit

Compare the "in " statements in the results file with the corresponding print statements in the override.inc file to better understand when the recovery functions are automatically called.

Modifying the Recovery System to Capture an Application Screen Shot Upon Error(s)

The first step to implement this is to decide which recovery system should be overridden to accomplish the above. In the above section it explains that the "DefaultTestCaseExit" includes "logs exceptions to the results file by default if there were any". We will override DefaultTestCaseExit to capture an application screen shot if the exception count is non-zero.

The next step is to copy the DefaultTestCaseExit function and rename it to TestCaseExit.

[-] TestCaseExit (BOOLEAN bException)
      [+] if (bException)
            [ ] ExceptLog ()
      [+] else
            [+] do
                  [ ] @"Browser".WaitForReady ()
            [ ] except
      [ ] 
      [ ] SetBaseState ()

The bException flag will be TRUE if the exception count is non-zero. So add code to the if (bException) block to capture a bitmap of the Desktop using SilkTest"s CaptureBitmap method. Its better to capture the desktop than just the application as it gives a wider

A few notes about the "new" TestCaseExit:

  • The bitmap capture code in wrapped in a do .. except block so that a problem with or failure of the bitmap capture doesn"t abort the script or test plan that"s executing.
  • The date and time are used to create a unique bitmap filename in the form "Desktop__.bmp".
  • The bitmap is saved in the same directory as the calling script using the CurrentPath keyword.
  • Before capturing the bitmap, the Agent option "bitmap match count" is set to 0 so that the bitmap is captured as quickly as possible. According to good programming practices, the bitmap match count is reset to its previous value after the bitmap is captured.

[-] TestCaseExit (BOOLEAN bException)
      [ ] Print ("in TestCaseExit")
      [ ]
      [-] if (bException)
            [ ] ExceptLog ()
            [ ] // set bitmap match count to zero, we don"t care about bitmap stabilization
            [ ] integer iOldMatchCount = Agent.SetOption (OPT_BITMAP_MATCH_COUNT, 0)
            [ ] // wrap bitmap capture in do...except; don"t want script/plan to abort if
            [ ] //       there"s a problem with the bitmap capture
            [-] do
                  [ ] // make unique filename based on date and time "now"
                  [ ] string sBitmapFilename = "{CurrentPath}\Desktop_{StrTran (DateStr (), "/", "")}_{StrTran (TimeStr (), ":", "")}.bmp"
                  [ ] Desktop.CaptureBitmap (sBitmapFilename)
                  [ ] Print ("*** Bitmap of Desktop saved to "{sBitmapFilename}"")
            [-] except
                  [ ] ExceptLog ()
            [ ] // restore previous value for bitmap match count
            [ ] Agent.SetOption (OPT_BITMAP_MATCH_COUNT, iOldMatchCount)
      [-] else
            [-] do
                  [ ] @"Browser".WaitForReady ()
            [ ] except
      [ ] 
      [ ] SetBaseState ()

Re-running the script with the "new" TestCaseExit produces the following in the results file:

[ ] Script override.t - 1 error
[ ] 
[ ] in ScriptEnter
[-] Testcase FirstTestcase - Passed
      [ ] in TestCaseEnter
      [ ] in the testcase named FirstTestcase
      [ ] in TestCaseExit
[-] Testcase SecondTestcase - 1 error
      [ ] in TestCaseEnter
      [ ] in the testcase named SecondTestcase
      [ ] in TestCaseExit
      [ ] *** Error: Divide by zero
      [ ] Occurred in SecondTestcase at override.t(9)
      [ ] *** Bitmap of Desktop saved to "Desktop_030303_152044.bmp"
[ ] in ScriptExit

Note that the failure in SecondTestcase caused a bitmap (screen shot) of the Desktop to be saved to a file named Desktop_030303_152044.bmp.
It"s then a simple matter of opening the screen shot in Microsoft Paint (or your graphics tool of choice) and using the picture of the Desktop and the text in the results file to decipher what caused the exception.



DISCLAIMER:

Some content on Community Tips & Information pages is not officially supported by Micro Focus. Please refer to our Terms of Use for more detail.
Top Contributors
Version history
Revision #:
1 of 1
Last update:
‎2013-02-15 19:24
Updated by:
 
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.