Highlighted
Contributor.
Contributor.
487 views

Mobile Devices: Leveraging UFT for functional testing a mobile device scanner

The UFT (Unified functional Testing) automation tool can be leveraged for functional testing of mobile devices.  This can be done without extended support for mobile if the device application also supports a windows terminal emulator.  This testing has been ongoing in a demonstration lab, which supports development of a HandHeld tag-up solution for the Verterans Administration (VA).
At VA hospitals clinicians are involved in an inventory tagging process.  Handheld scanners require information about assets and locations. This information is critical to ensure proper tag commissioning (in other words, associating an asset with a Radio Frequency Identification [RFID] tag) and accurate synchronization of asset information between VA systems.HandHeld.png

 Batch Commissioning Process:
Facilities have many existing assets within their asset management system. In order for those assets to be tracked, they must be commissioned. Commissioning an asset means creating an asset record for the asset, physically affixing an RFID tag to the asset, and finally, associating the RFID tag to the asset.  The clinicians commission assets using mobile device scanners.  The commissioned assets data is stored in the devices local starage and then transmitted to an ESB middle ware data base, which interfaces with other VA systems.  Prior to beginning a clinical shift, the device scanners are synced to the middleware ESB data base.  It is critical the device scanner local data is in sync with the middleware ESB.

How UFT was leveraged to validate local device storage is in sync with the ESB

In the development lab, multiple device scanners first complete a commissioning assets run.  Next,  UFT automation scripts validate the devices are properly synched to the ESB  using the process below:

  • Save ESB middleware data and device local storage data to text files.
  • Read text files into data arrays
  • Compare the two data arrays.

 The device transaction flow diagram and UFT implementations are included below with actual code samples:  Mobile Device Logical DiagramMobile Device Logical Diagram

 What the UFT script does to validate the Handheld local storage is in sync with the ESB middleware layer:

Creates a Comm object for a Firefox browser and invokes Firefox

Syntax:

url = "ESB service endpoint database link"
Set WshShell = CreateObject("WScript.Shell")
Call WshShell.Run("firefox.exe")
Call WshShell.Run("firefox.exe "& url, 3, false)

 Authenticaes Firefox and creates and XL Pivot table of ESB Handheld transaction status for each Handheld session

Note:  standard recording and the object repository were uilized.  The Web add-in is required.

Saves the XL Pivot table to the run folder log in xlsx format

 Note:  standard recording and the object repository were uilized.  The Web add-in is required.

Filters processes for FireFox .exe and terminates the process

Syntax:

Call = Process ( "firefox.exe", "Filter", "Yes" )

Function:

############################################################
'#  Public Function Process ( oProcess, sAction, sKill )
'# DESCRIPTION:
'#      This function creates an array of all  system processes on the local computer.  The 
'#       contents of the array is either listed or filter depending upon user input.  The
'#      user may terminate the filtered process if "Yes"  is input for the third parameter.
'# PARAMETERS:
'#      oProcess
'#          [IN] Complete system process name. i.e. notepad.exe or empty "" for listing
'#      sAction
'#         [IN] "List" or "Filter"
'#     sKill
'#         [IN] "Yes" or "No"
'#          [OUT]   For List only returns a "Pass"
'#          [OUT]  For filtering returns the Process name if cound or "Fail" if not found
'# RETURNS:
'#      "Pass" on success
'#      "Fail" on failure
'# Sample Calls
'#   List All Local System Procceses:   rc = Process ( "", "List", "" )
'#  Filter for Notepad executable:  rc = Process ( "notepad.exe", "Filter", "No" )
'#  Filter for Notepad executable and Kill the Process:  rc = Process ( "notepad.exe", "Filter", "Yes" )
'# ERRORS:  None
'# Orig Author: Jim Burton
'# Orig Date  : 00/00/2015
'# History:
'# 00/00/00  Author       Change details
########################################################################
Public Function Process ( oProcess, sAction, sKill )
Process = "Pass"
RunMode = "Fast"
Dim objWMIService, objProcess, colProcess
Dim strComputer
'Identification for local computer
strComputer = "."
Set WshShell = CreateObject("WScript.Shell")
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _ 
& strComputer & "\root\cimv2") 
Set colProcess = objWMIService.ExecQuery _
("Select * from Win32_Process")
Set asProcess = CreateObject( "System.Collections.ArrayList" )  'Array for Processes
j = 0
For Each objProcess in colProcess
	asProcess.Add objProcess.Name
	 j=j+1
Next
For i = 0 to j - 1
	Select Case  sAction
		Case "List"
		       Print asProcess(i)
		Case "Filter"
		     If ( InStr ( oProcess, asProcess(i) ) ) > 0 then
		        Print asProcess(i)		
		        Process = asProcess(i)
		     If sKill = "Yes" Then
                                       Print "Process Terminated: "  & asProcess(i)
			Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name =" & "'" & oProcess & "'" )
			For Each objProcess in colProcessList 
				objProcess.Terminate()
			Next
		      end If
			RunMode = "Normal"
			Exit Function
		       else
			Process = "Fail"
		      end if
		Case Else
	End Select
Next
RunMode = "Normal"
End Function
'############################################################

Creates a comm object for the Firefox browser and invokes Firefox a second time

Syntax:

url = "ESB service endpoint database link"
Set WshShell = CreateObject("WScript.Shell")
Call WshShell.Run("firefox.exe")
Call WshShell.Run("firefox.exe "& url, 3, fals 

 Authenticates Firefox and opens a text file of ESB handheld transaction status

 Note:  standard recording and the object repository were uilized.  The Web add-in is required.

Saves the text file to the local UFT work folder: 

C:\RTLS\RTLS Automation\Work\AssetsDataESB.txt

Note:  standard recording and the object repository were uilized.  The Web add-in is required.

Filters processes for Firefox.exe and terminates the process

Note:  Same syntax as above

Reads the local device storage into a single data array

Syntax:

sAssetName = TextFileToArraySingle ("C:\App Data\ScannerApp\" & "AssetsData.txt", "")

Function:

'############################################################
'# Public Function TextFileToArraySingle (sFileName, sDelimeter)
'# DESCRIPTION:
'#This Function reads a text file separated by a delimiter and returns an array.
'#This function can be useful *  when you are creating a data driven framework using
 '#text file and like to retrieve data from text file instead using other source. 
'# Input Variables:
'#    [In]     sFileName - Text file name with text separated by a delimiter
'#    [In]     sDelimeter -  Delimeter value
'# RETURNS:  1 - Dimensional array in memory
'# ERRORS: none
'# SAMPLE CALL:  
'#	rc = TextFileToArray("c:\TextFiletoArray.txt", "$")
'# HISTORY:
'# Orig Authors: Rasel Anan
'# Orig Date   : 00/00/2012
'############################################################################
Public Function TextFileToArraySingle (sFileName, sDelimeter)		
Const sFunctionName = "TextFileToArraySingle"
	On Error Resume Next
If  sFileName <> "" Then
	rc = FileSysObjExists( "FILE", sFileName) 
		If rc = False Then
			Print "Probable File Does Not exist"
			Exit Function
		end if
	rc = FileSysObjGetValue( "GETEXTENSIONNAME", sFileName, "" ) 
	If rc <> "txt" Then
		Print "File is Not a Txt File"
		Exit Function
	end if
	Const ForReading = 1
	Dim sArray()
	Set objFSO = CreateObject("Scripting.FileSystemObject")
	Set objTextFile = objFSO.OpenTextFile (sFileName, ForReading)
	  sCount = 0
	Do Until objTextFile.AtEndOfStream  'Returns true if the file pointer is at the end of a TextStream file; false if it is not. Read-only.
	strNextLine = objTextFile.Readline       
	arrServiceList = Split(strNextLine , sDelimeter)  
		On Error Resume Next
		If   sCount = 0 or Ubound(sArray) < sCount Then
		     ReDim Preserve sArray(UBound(arrServiceList))
		End If
		For i = 0 to  (Ubound(arrServiceList)) 
			sArray(i) = arrServiceList(i)
			TextFileToArraySingle=TextFileToArraySingle &"*" & sArray(i)  
		Next
		sCount = sCount + 1
	Loop
	Set objFSO = Nothing
	Set objTextFile = Nothing
End If
End Function 
'############################################################

Splits data into a one-dimensional array containing a specified number of substrings.

Syntax:

asAssets = Split(sAssetName, "00.000" ) 

Filter the AssetsData.txt file for Handheld transaction status and count transaction types (Acknowledged, Failed, Transmitted)

Syntax:

A1Count = 0
T1Count = 0
F1Count = 0
A2Count = 0
T2Count = 0
F2Count = 0
A3Count = 0
T3Count = 0
F3Count = 0

For i = 0 to Ubound (asAssets)
		If instr(asAssets(i),"A^0001") > 0  and _
		   instr (asAssets(i),Environment.Value ("Device1")) > 0 Then
			Print asAssets(i)
			A1Count = ( A1Count + 1 )
		End If
		If instr(asAssets(i),"T^0001") > 0  and _
	       	   instr (asAssets(i),Environment.Value ("Device1")) > 0 Then
			Print asAssets(i)
			T1Count = ( T1Count + 1 )
		End If
		If instr(asAssets(i),"F^0001") > 0  and _
	      	  instr (asAssets(i),Environment.Value ("Device1")) > 0 Then
			Print asAssets(i)
			F1Count = ( F1Count + 1 )
		End If
		If instr(asAssets(i),"A^0001") > 0  and _
		   instr (asAssets(i),Environment.Value ("Device2")) > 0 Then
			Print asAssets(i)
			A2Count = ( A2Count + 1 )
		End If
		If instr(asAssets(i),"T^0001") > 0  and _
	                   instr (asAssets(i),Environment.Value ("Device2")) > 0 Then
			Print asAssets(i)
			T2Count = ( T2Count + 1 )
		End If
		If instr(asAssets(i),"F^0001") > 0  and _
	                  instr (asAssets(i),Environment.Value ("Device2")) > 0 Then
			Print asAssets(i)
			F2Count = ( F2Count + 1 )
		End If
		If instr(asAssets(i),"A^0001") > 0  and _
		   instr (asAssets(i),Environment.Value ("Device3")) > 0 Then
			Print asAssets(i)
			A3Count = ( A3Count + 1 )
		End If
		If instr(asAssets(i),"T^0001") > 0  and _
	                  instr (asAssets(i),Environment.Value ("Device3")) > 0 Then
			Print asAssets(i)
			T3Count = ( T3Count + 1 )
		End If
		If instr(asAssets(i),"F^0001") > 0  and _
	                  instr (asAssets(i),Environment.Value ("Device3")) > 0 Then
			Print asAssets(i)
			F3Count = ( F3Count + 1 )
		End If
Next

vAck_GrandTotal = ( A1Count + A2Count + A3Count )
vTran_GrandTotal = ( T1Count + T2Count + T3Count )
vFail_GrandTotal = ( F1Count + F2Count + F3Count )
vMyGrandTotal = ( vAck_GrandTotal + vTran_GrandTotal + vFail_GrandTotal )

Creates a data array of the local Handheld transaction status counts

Syntax:

Set asSummaryArray = CreateObject( "System.Collections.ArrayList" ) 
asSummaryArray.Add  A1Count
asSummaryArray.Add  T1Count
asSummaryArray.Add  F1Count
asSummaryArray.Add  A2Count
asSummaryArray.Add  T2Count
asSummaryArray.Add  F2Count
asSummaryArray.Add  A3Count
asSummaryArray.Add  T3Count
asSummaryArray.Add  F3Count
asSummaryArray.Add  vAck_GrandTotal
asSummaryArray.Add  vTran_GrandTotal
asSummaryArray.Add  vFail_GrandTotal
asSummaryArray.Add  vMyGrandTotal

 Reads the ESB transaction status text file (AssetsDataESB.txt) into a single data array

Syntax:

asESBName = TextFileToArraySingle (Environment.Value ("TEST_WORK_AREA") & "AssetsDataESB.txt", "")

Splits data into a one-dimensional array containing a specified number of substrings

 Syntax:

asESBAssets = Split(sESBName, "636^636 " )

Filters the AssetsDataESB.txt file for Handhled transaction status and counts transaction types (Acknowledged, Failed, Transmitted)

A1ESBCount = 0
T1ESBCount = 0
F1ESBCount = 0
A2ESBCount = 0
T2ESBCount = 0
F2ESBCount = 0
A3ESBCount = 0
T3ESBCount = 0
F3ESBCount = 0
	
For i = 0 to Ubound (asESBAssets)	
		MyStr = Right(asESBAssets(i), 5)
		If instr(MyStr,"^A^") > 0  and _
		   instr (asESBAssets(i),Environment.Value ("Device1")) > 0 Then
			Print asESBAssets(i)
			A1ESBCount = ( A1ESBCount + 1 )
		End If	
		If instr(asESBAssets(i),"^T^") > 0  and _
	       instr (asESBAssets(i),Environment.Value ("Device1")) > 0 Then
			Print asESBAssets(i)
			T1ESBCount = ( T1ESBCount + 1 )
		End If
		If instr(asESBAssets(i),"^F^") > 0  and _
	       instr (asESBAssets(i),Environment.Value ("Device1")) > 0 Then
			Print asESBAssets(i)
			F1ESBCount = ( F1ESBCount + 1 )
		End If
		If instr(MyStr,"^A^") > 0  and _
		   instr (asESBAssets(i),Environment.Value ("Device2")) > 0 Then						Print asESBAssets(i)
			A2ESBCount = ( A2ESBCount + 1 )
		End If
		If instr(asESBAssets(i),"^T^") > 0  and _
	       instr (asESBAssets(i),Environment.Value ("Device2")) > 0 Then
			Print asESBAssets(i)
			T2ESBCount = ( T2ESBCount + 1 )
		End If
		If instr(asESBAssets(i),"^F^") > 0  and _
	       instr (asESBAssets(i),Environment.Value ("Device2")) > 0 Then
			Print asESBAssets(i)
			F2ESBCount = ( F2ESBCount + 1 )
		End If
		If instr(MyStr,"^A^") > 0  and _
		   instr (asESBAssets(i),Environment.Value ("Device3")) > 0 Then
			Print asESBAssets(i)
			A3ESBCount = ( A3ESBCount + 1 )
		End If
		If instr(asESBAssets(i),"^T^") > 0  and _
	       instr (asESBAssets(i),Environment.Value ("Device3")) > 0 Then
			Print asESBAssets(i)
			T3ESBCount = ( T3ESBCount + 1 )
		End If
		If instr(asESBAssets(i),"^F^") > 0  and _
	       instr (asESBAssets(i),Environment.Value ("Device3")) > 0 Then
			Print asESBAssets(i)
			F3ESBCount = ( F3ESBCount + 1 )
		End If
Next
	
vAck_ESBGrandTotal = ( A1ESBCount + A2ESBCount + A3ESBCount )
vTran_ESBGrandTotal = ( T1ESBCount + T2ESBCount + T3ESBCount )
vFail_ESBGrandTotal = ( F1ESBCount + F2ESBCount + F3ESBCount )
vMyGrandTotalESB = ( vAck_ESBGrandTotal + vTran_ESBGrandTotal + vFail_ESBGrandTotal )

Creates a data array of the ESB transaction status counts

Syntax:

Set asESBSummaryArray = CreateObject( "System.Collections.ArrayList" ) 
asESBSummaryArray.Add  A1ESBCount
asESBSummaryArray.Add  T1ESBCount
asESBSummaryArray.Add  F1ESBCount
asESBSummaryArray.Add  A2ESBCount
asESBSummaryArray.Add  T2ESBCount
asESBSummaryArray.Add  F2ESBCount
asESBSummaryArray.Add  A3ESBCount
asESBSummaryArray.Add  T3ESBCount
asESBSummaryArray.Add  F3ESBCount
asESBSummaryArray.Add  vAck_ESBGrandTotal
asESBSummaryArray.Add  vTran_ESBGrandTotal
asESBSummaryArray.Add  vFail_ESBGrandTotal
asESBSummaryArray.Add  vMyGrandTotalESB

Compares the ESB transactions count data array with the local AssetsData.txt data array using CompareTwoArrays function

Syntax:

vResults =  CompareTwoArrays ( asESBSummaryArray, asSummaryArray, 13)

Function:

'############################################################
'*  Public Function CompareTwoArrays ( ExpArray, ActArray, vCountArray)
'*  This function compares multiple values in an array.   
'*  Author:	Jim Burton
'*  Inputs    - vExpArray - Expected Array List
'*                 -  vActArray - Actual Array List
'*                 -  vCountArray -  Total count of items in array list
'*  Returns  - Compare Array Pass = True,  Compare Array Failed = False
'*  sample calls:  rc = CompareTwoArrays ( vExpArray, vActArray, 11)
'############################################################
Public Function CompareTwoArrays ( vExpArray, vActArray, vCountArray )
	CompareTwoArrays =True
	For i=0 to vCountArray-1
		If  vExpArray(i)<>"0" Then
			print "vExpArray(i) " & vExpArray(i)
			print "vActArray(i) " & vActArray(i)
			If vExpArray(i)=vActArray(i) Then
		    		 'log compare passed
			else
				'log compare failed
		       		CompareTwoArrays = False
			End If
		End if
	Next
End Function
'############################################################

If the CompareTwoArrays function returns True, the ESB is in sync with the local Handheld AssetsData.txt file and the test is a Pass

Syntax:

If vResults <> False Then
      gtRTLS.g_General = True
Else
gtRTLS.g_General = False End If

 Automatically generates a local Handheld transaction status Excel graphical report in xlsx format

Note:  The code and framework for this step is not included in this Blog post

Copies the log folder into the UFT run folder

Syntax:

Call FileSysObjAction( "COPYFILE", Result , gtRTLS.g_DocPath & "\" & TestName & ".log" )

Function:

'############################################################
'# Public Function FileSysObjAction(sAction, vArg1, vArg2 ) 
'# DESCRIPTION:
'#    Use FileSystem object to execute file system actions. 
'#   Actions : BUILDPATH, COPYFILE, COPYFOLDER, CREATEFOLDER, 
'#   CREATETEXTFILE, DELETEFILE, DELETEFOLDER, MOVEFILE, MOVEFOLDER, 
'# 
'# PARAMETERS:  
'#       [In ]    sAction  =  sAction (see list above)
'#	  [In ]    vArg1   =   As Required (Usually file or folder string)
'#	  [In ]    vArg2   =   As Required (Usually file or folder string)
'#   
'# EXAMPLE:    
'#		rc = FileSysObjAction( "COPYFOLDER", "c:\temp1", "c:\temp2" ) 
'# RETURNS:  TRUE on success, FALSE on failure
'# ERRORS:
'#       none
'# HISTORY:
'# Orig Author: Jim Burton
'# Orig Date  : 00/00/2012
'# Change History:
'# 00/00/00  Author       Change details
'############################################################################
Public Function FileSysObjAction(sAction, vArg1, vArg2  ) 
    Dim Result, Result1, Result2
    Dim objFSO
	Const sFunctionName = "FileSysObjAction" 
    FileSysObjAction = FALSE
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Select Case Ucase(sAction)
        Case "BUILDPATH"
           	Result1 = FileSysObjExists( "FOLDER", vArg1) 
		Result2 = FileSysObjExists( "FILE", vArg2)
		If Result1 = False or _
		Result2 = False Then
			MsgBox "Folder or File probably doesn't exist" 							Exit Function
		End If
           	 Result = objFSO.BuildPath(vArg1, vArg2)
		FileSysObjAction = Result
		Exit Function
        Case "COPYFILE"
           	Result1 = FileSysObjExists( "FILE", vArg1) 
		Result2 = FileSysObjExists( "FILE", vArg2)
		If Result1 = False or _
		Result2 = False Then
			MsgBox "CopyFile.  Probable invalid argument:"  
			Exit Function
		End If
           	On Error Resume Next
            	Result = objFSO.CopyFile(vArg1, vArg2, TRUE)
        Case "COPYFOLDER"
		Result1 = FileSysObjExists( "FOLDER", vArg1) 
		Result2 = FileSysObjExists( "FOLDER", vArg2)
		If Result1 = False or _
		Result2 = False Then
			MsgBox "CopyFolder.  Probable invalid argument:"  
			 Exit Function
		End If
            	On Error Resume Next
            	Result = objFSO.CopyFolder(vArg1, vArg2, TRUE)
        Case "CREATEFOLDER"
            	Result1 = FileSysObjExists( "FOLDER", vArg1 ) 
		If Result1 = True Then
			MsgBox "Folder probably already exists:"  
			Exit Function
		End If
		On Error Resume Next
               	Result = objFSO.CreateFolder ( vArg1 )
        Case "CREATETEXTFILE"
		Result1 = FileSysObjExists( "FILE", vArg1) 
		If Result1 = True Then
			MsgBox "Text File probably already exists:"  
			Exit Function
		End If
           	On Error Resume Next
           	 Result = objFSO.CreateTextFile ( vArg1 ) 
		objFSO.close
        Case "DELETEFILE"
           	Result1 = FileSysObjExists( "FILE", vArg1) 
		If Result1 = False Then
			MsgBox File probably does not exist:"  
			Exit Function
		End If
            	On Error Resume Next
            	Result = objFSO.DeleteFile ( vArg1 )     'default to Force=False (for read-only)
        Case "DELETEFOLDER"
		Result1 = FileSysObjExists( "FOLDER", vArg1 ) 
		If Result1 = False Then
			MsgBox "Folder probably doesn't exist:"  
			Exit Function
		End If
            	On Error Resume Next
           	 Result = objFSO.DeleteFolder ( vArg1 )     'default to Force=False (for read-only)
        Case "MOVEFILE"
		Result1 = FileSysObjExists( "FILE", vArg1) 
		Result2 = FileSysObjExists( "FOLDER", vArg2)
		If Result1 = False or _
		Result2 = False Then
			MsgBox "Source file or target path does not exist:" 
			Exit Function
		End If
            	On Error Resume Next
           	Result = objFSO.MoveFile ( vArg1, vArg2 )
        Case "MOVEFOLDER"
          	Result1 = FileSysObjExists( "FOLDER", vArg1) 
		Result2 = FileSysObjExists( "FOLDER", vArg2)
		If Result1 = False or Result2 = False Then
			MsgBox "Source folder does not exist or target path does exist"  
			      Exit Function
		End If
            	On Error Resume Next
            	Result = objFSO.MoveFolder ( vArg1, vArg2 )
             	If err.number <> 0 Then
			'Error Handler Code		
		End If
		On Error GoTo 0  'Disables error handing
              Case Else
    End Select
    FileSysObjAction = TRUE 
End Function  'Public Function FileSysObjAction(sAction, vArg1, vArg2  ) 
'############################################################

Automatically EMAILS the test results to the development team with the xlsx attachments and test log

Other Considerations:

 The automation code required to create a graphical Handheld scanning status report and email the report to the development team is not covered in this Blog.   This may be covered in a future Blog post.  
Thank you,

James Burton
Senior Automation Engineer
RTLS testing for Military Health & Veterans Affairs

0 Likes
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.