«

»

Aug 16 2016

Using Assertions to Control the Script Flow

In computer programming, an assertion is a statement that a predicate (Boolean-valued function, a true–false expression) is expected to always be true at that point in the code. If an assertion evaluates to false at run time, an assertion failure results, which typically causes the program to crash, or to throw an assertion exception.

Source: Wikipedia

This short article describes how to implement an ASSERT method in UFT* that:

  1. Executes a predefined recovery procedure or exit point for a value returned by a method and hence
  2. Enables data-driven error handling
  3. Makes code more concise and hence more readable and simple to write

*The method described here is basically generic and, though the specifics may well vary, it can be implemented for other tools as well.

Step 1: Defining the Triggers-Procedures Pairs

The first step is to define which procedure is invoked for each value a method can return. For the sake of simplicity, in this example the definitions will be included in a XML file to be loaded as Environment variables to UFT.

<environment>	
	<variable>
		<name>TRIGGER_0</name>
		<value>< ![CDATA[]]></value>
	</variable>
	<variable>
		<name>TRIGGER_1</name>
		<value>< ![CDATA[ExitTestEx]]></value>
	</variable>
	<variable>
		<name>TRIGGER_2</name>
		<value>< ![CDATA[]]></value>
	</variable>
	<variable>
		<name>TRIGGER_3</name>
		<value>< ![CDATA[]]></value>
	</variable>
	<variable>
		<name>TRIGGER_4</name>
		<value>< ![CDATA[]]></value>
	</variable>
</environment>

The file includes variables named with the prefix TRIGGER_. For instance, TRIGGER_1 defines what to do in case a fail value (micFail = 1) is returned by a method. Typically for a micPass (0), micDone (2), or micInfo (4) returned value there is nothing to do, so there is no need to define them. As shown below, the ASSERT method will ensure nothing is done in these cases. However, for the sake of completeness they were included in the above XML.

Step 2: Writing the UFTStopTest.vbs (external script) and adding its path to the Environment file

Write the following code and save it as UFTStopTest.vbs in C:/Automation/Scripts/.

Dim qtApp
 
Set qtApp = CreateObject("Quicktest.Application")
 
qtApp.Test.Stop
 
Set qtApp = Nothing

Define the path to the above script in the UFT_STOP_SCRIPT Environment variable.

<environment>
	<!--continued-->
	<variable>
		<name>UFT_STOP_SCRIPT</name>
		<value>< ![CDATA[C:/Automation/Scripts/UFTStopTest.vbs]]></value>
	</variable>
 
</environment>

Step 3: Writing the ASSERT method

The ASSERT method accepts an argument (usually an integer between 0-4, as UFT’s reporting codes) and retrieves from the Environment the value of the function associated with the trigger. If none is found, then an empty string is assigned. The <span style=”color: blue;”>Execute< .SPAN> command invokes the associated function; if ASSERT is empty then no code is being run.

Function ASSERT(ByVal intTriggerCode)	
	On Error Resume Next
	ASSERT = Environment("TRIGGER_"&intTriggerCode)
	If(Err.Number<>0)Then 
		Err.Clear
		ASSERT = ""		
	End If
	Execute(ASSERT)
End Function

Step 4: Writing the ExitTestEx method

Function ExitTestEx uses UFT’s COM object to attempt stopping the test. Note: I tried to run Execute(“ExitTest”) and the results were not reliable. Sometimes the test ended and other it didn’t, so I decided to try a different approach that involves an external script which is invoked by UFT to stop the currently running test.

Function ExitTestEx()
	Dim Shell
 
	Print "Exiting test " & Environment("TestName")
	Set Shell = CreateObject("Wscript.Shell")
	ExitTestEx = Shell.Run("CMD /C "&Environment("UFT_STOP_SCRIPT"), 1, false)
	Set Shell = Nothing
End Function

Step 5: Using the ASSERT method

ASSERT(MyFunction(param1, ..., paramN))

How it works

The ASSERT method retrieves the value of the procedure defined for a specific returned value from MyFunction, and executes it. Following the example shown in Step 1 above, a return value of 1 (micFail) would trigger the ExitTestEx method, while if a micPass, micWarning, micDone or micInfo value is passed nothing would occur. The ExitTestEx method invokes an external vbs which commands the test to stop via UFT’s COM object.

Of course, in case of failure the function must return a valid trigger code to invoke the appropriate recovery procedure or command. For this reason, using this mechanism with UFT methods like Exist, WaitProperty, CheckProperty and Check – which return true or false – is inadequate. However, in GUI test automation, one finds quite often the need to wait for some event to occur, such as the opening or closure of a dialog or window. In most cases, if a failure on such steps occurs then it is pointless to attempt to execute the following steps. For this reason it would be of great utility to override these methods (using RegisterUserFunc which will not be covered here) so that they comply with the standard zero (micPass) for success and one (micFail) for failure.

Using ASSERT for Error Handling

The method described above can be very useful also to control the flow when exceptions are thrown or other issues are found during runtime. For example, to handle any error in a function and stop the run, use the following method:

Function MyFunction(ByVal param1, ..., paramN)
	On Error Resume Next
	MyFunction = 0 'micPass
	'--- Start: Your code here
	'--- 
	'--- 
	'--- End: Your code here
	If(Err.Number<>0)Then
		MyFunction = 1 'ExitTest		
	End If
End Function

So, when calling MyFunction it will return 0 if no error occurred and 1 if something got wrong. The ASSERT method will get the ExitTestEx value for the TRIGGER_1, and Execute it. This pattern saves the need to use multiple if statements in your code to control its flow.

About Meir Bar-Tal

Meir Bar-Tal is an Automation Architect with extensive technical, educational and leadership experience in Software Design, Development and Testing. For many years Meir has helped companies establish solid foundations for their testing activities with a wide variety of software applications and systems and across different technologies and platforms. Meir is a well-known expert in Data-Driven, Keyword Driven and Hybrid methodologies and has published a number of influential articles on the applications of Design Patterns to Test Automation. For the last five years, he has been pushing forward an ambitious program towards the development of an Object Oriented automation framework named Sunscrit, a huge project which is still underway. Meir is the owner of www.AdvancedQTP.com of which he was a co-founder in 2007 and served as its Editor in Chief, Author and Forums Administrator ever since. Meir lives in Israel and cooperates closely with HP R&D and other colleagues to improve the user experience and productivity with HP Software tools.