Saturday, December 13, 2008

Close the AUT after certain time

In recent days, I am trying to kill the applications if they are unable to close by the tool (SilkTest). Last month, I was solving one different issue.

We are having ten years old test suite and it was not updated for last two years due to product priorities. The total execution time for this regression suite is around 70 hours. Many times, our AUT is getting hung or the current window focus is unable to shift and suite is unable to continue after that. We endup to stop the suite at that script and re-ran the remaining scripts manually. Also we are unable to use weekends fully for the regression.

I planned to run the scripts as unattended. It is intermittent problem. Often silktest not executed in different testcases and not in one particular case always. So I thought to kill the application if the application is running more than 45 minutes. Few of silktest group members have given a idea and I have implemented it.

Silktest has 'spawn' statement to create a separate thread and it is used to execute MultiTestcase. MultiTestcae helps to run the particular code in multiple systems. Also I used PsList to get the running time of an application. I have tried few scenarios with Notepad and then finally put into our suite. This solution is worked..!!!

I have called in script level and I called 'spawn' statement in ScriptEnter and break the loop, once the execution reached ScriptExit. I have given the code below...

4Test code for ScriptEnter and ScriptExit



[+] void ScriptEnter ()
[ ] // Added for Unattended execution
[ ] gbAppKill = TRUE
[+] spawn
[ ] KillApp_UsedTime ("myAut",2700)
[ ]
[+] void ScriptExit (boolean bException)
[ ]
[ ] // Added to stop kill thread
[ ] gbAppKill = FALSE
[ ]



4Test methods to find the exeuction time and killing it


[ ] // // **** Code written for killing apps if app is running more than 45 mins.
[ ] // Methods
[ ] Boolean gbAppKill
[ ]
[+] Void KillApp_psKill (STRING sApp)
[ ] List of STRING lsOutput
[ ]
[ ] STRING sCommand = "{gcsToolsPath}\pskill {sApp} "
[ ]
[+] do
[ ]
[ ] Print ("Executing command: {sCommand}")
[ ] SYS_Execute (sCommand, lsOutput)
[ ] ResPrintList ("Command Output", lsOutput)
[ ] Print ("echo App {sApp} killed at %DATE%_%TIME% >> d:\kill.txt ")
[ ] SYS_Execute ("echo App {sApp} killed at %DATE%_%TIME% >> d:\kill.txt ")
[ ] Sleep (2)
[+] except
[ ] // Do Nothing
[ ] ExceptLog ()
[ ]
[ ]
[-] VOID KillApp_UsedTime (STRING sApp, INTEGER iKillTimeLimit optional)
[ ] List of STRING lsOutput
[ ] INTEGER iItem, iTotalValue, iTimes, iCount,iSleepTime
[ ] STRING sPartial,sItem,sPID
[ ] STRING sTime, sHour, sMin, sSec
[ ] STRING sCommand = "{gcsToolsPath}\pslist {sApp}"
[ ]
[ ] //sPID = ""
[ ]
[-] do
[ ]
[ ] iSleepTime = 50 //Seconds
[+] if (IsNull (iKillTimeLimit))
[ ] iKillTimeLimit = 6 // Seconds.
[ ]
[ ]
[ ] iCount = (iKillTimeLimit/iSleepTime) * 100 + 1+10
[ ]
[-] for iTimes=1 to iCount
[+] if (! gbAppKill)
[ ] Print ("gbAppKill is FALSE and exiting from Spawn thread..")
[ ] break
[ ]
[ ]
[ ] Sleep (iSleepTime)
[ ]
[ ]
[ ] Print ("Executing command: {sCommand}")
[ ] SYS_Execute (sCommand, lsOutput)
[ ] ResPrintList ("Command Output", lsOutput)
[ ]
[+] for iItem=2 to ListCount (lsOutput)
[ ] sItem = lsOutput[iItem]
[+] if (MatchStr ("{sApp}*",sItem))
[ ]
[ ] sSec = GetField (sItem,":",5)
[ ]
[+] if (IsNull(sSec) || (Trim(sSec) == ""))
[ ] continue
[+] else
[ ] sTime = GetField (sItem,":",3)
[ ] sMin = GetField (sItem,":",4)
[ ] sHour = SubStr (sTime,Len(sTime)-3)
[ ]
[ ] Print ("Hour: {sHour}")
[ ] Print ("Minutes: {sMin}")
[ ] Print ("Seconds: {sSec}")
[ ] iTotalValue = Val (sMin) * 60 + Val(sHour) * 3600
[ ] Print ("App {sApp} - running total time: {iTotalValue} Seconds")
[ ]
[+] if (iKillTimeLimit <= iTotalValue)
[ ] Print ("Application {sApp} is running {iTotalValue} seconds -beyond expected time {iKillTimeLimit} seconds.")
[ ] KillApp_psKill (sApp)
[ ] Print ("Going to kill Application {sApp}")
[ ] // break // It is suitable for testcase level
[+] else
[ ] Print ("Application {sApp} is running {iTotalValue} seconds - not exceeding expected time {iKillTimeLimit} seconds.")
[ ] // return sPID
[ ]
[ ]
[ ]
[+] except
[ ] // Do Nothing
[ ]
[ ]
[ ]

Monday, December 8, 2008

Closing Excel instance by VBScript

We have a test suite for Excel plug-in. Silktest built-in function does not work for Excel 2007. It is working fine for Excel 2003. Silktest is unable to close the Excel 2007 instance. We used Taskkill to kill the excel. It has created few other issues. I was looking for alternative solution. So I decided to write a vb script and got success. I have given the code below.

VBS code - To close Excel

'------------------------------------------------------------------------- ' File : CloseExcel.vbs ' Author : Palani ' Purpose : To close the excel, if it is already opened. ' '' Revision History: ''$Log: CloseExcel.vbs,v $ '' '------------------------------------------------------------------------- '' Usage '' cscript D:\rpm_scripts_palani\tools\CloseExcel.vbs '' cscript CloseExcel.vbs '******** Variables Declaration Dim gsLogFile '******** Function calls call CloseExcelApps () '-------------------------------------- ' Method : CloseExcelApps ' Author : T. Palani Selvam ' Purpose : Close Excel application. ' Parameters: - Nil ' Returns : - Nil ' Caller : - Nil ' Calls : - Nil '-------------------------------------- Sub CloseExcelApps() Dim sExcelPath 'As Variant 'Excel file '********** Excel object declaration **********' ' Excel Application object Dim objExcel 'As Excel.Application Dim objExcel2 'As Excel.Workbooks Dim objXLWorkbook 'As Excel.Workbook On Error Resume Next Set objExcel = GetObject(,"Excel.Application") If Not (IsNull(objExcel) Or IsEmpty(objExcel)) Then WScript.Echo ("Excel application instance Exists..") 'Set objXLWorkbook = objExcel.ActiveWorkbook 'You can set this property to True if you want to close a modified workbook 'without either saving it or being prompted to save it. objExcel.ActiveWorkbook.Saved = True objExcel.ActiveWorkbook.Close objExcel.Application.Quit 'objExcel.Worksbooks.Close 'objExcel.Quit Set objExcel = Nothing Set objExcel2 = GetObject(,"Excel.Application") If Not (IsNull(objExcel2) Or IsEmpty(objExcel2)) Then Set objExcel2 = Nothing WScript.Echo ("FAIL. Excel application is not closed properly.") Else WScript.Echo ("PASS. Successfully closed Excel application.") End If WScript.Echo ("End - Closing excel application instance.") else WScript.Echo ("Excel application instance does not exist!....") End If End Sub

Sunday, November 2, 2008

Windows XP - System failure

Last month, My home PC did not boot at all. I searched the solutions on Internet and tried many things. Even Microsoft's knowledge base articles were not solved my problem.

Problem 1: winlogon.exe - Application Error
Initially I got the WinLogon.exe error dialog box and then it was restarted automatically again and again. The dialog box message was like below:
-----------------------------------------
winlogon.exe - Application Error
------------------------------------------
The instructions at "0x759723ee" referenced memory
at "0x00000000". The memory could not be "read".

Click on OK to terminate the program
Click on CANCEL to debug the program
-------------------------------------------

System was restarted, if I click OK butto or Cancel Button. Then I restarted the system by all startup modes. I have explained all these modes in my previous post - Strange behavior with Service Pack . None of the modes helped me. I got blue screen, while I was trying by startup mode - Disable Automatic restart on system failure. I searched on net and applied many solutions. None of them worked out...

Solution 1
From softwaretipsandtricks.com

  1. Boot with winxp cd
  2. Log in to recovery console
  3. chkdsk /r


Solution 2
This is a problem with virtual RAM, I've had it before with various steam games, try lowering the size of the paging file (I'm pretty sure you can do that from the recovery console) or deleting it completely just so you can log on, then set the paging file back up again, with a lower size. This problem also arises if you have page files on more than one hard disk, its better to have 1 3GB page than 2 1.5GB ones on separate hard disks.

Solution 3
It's simple, just download hijack.exe and killbox.exe. Run Hijack. Look for these types of process in the hijack log:
O20 - Winlogon Notify: arergiti - arergiti.dll
O20 - Winlogon Notify: bdicjulx - bdicjulx.dll (this is only an example, it will not be the same dll files in your case, just put the types of these trojans for your understanding) kill all these dll files comes under the heading "Winlogon notify" using killbox (use the option 'delete on reboot')..and it is simple as that...nothing to worry..Just check for Winlogon nofify errors and delete all these dlls which fall under this category (i.e. "winlogon notify")

Solution 4
mbrando.com
We’ve had 15-20 machines suddenly start doing this in the last month. I’ve narrowed it down to an issue with the RPC and DCOM services; by default they are both set to “Restart the computer” if they can’t start.
We’re still working with Microsoft to determine why this suddenly started, but we have at least figured out that after several reboots and if you let it sit at the logon screen for a while before attempting to logon, you can sometimes get it to boot all the way into Explorer. If you get that lucky, go into your services and set the recovery options for both services to “Restart the service” instead of “Restart the computer”.

Solution 5
I had the same issue and I was able to hit CTRL+ALT+DEL before the error message popped up and then login and do a system restore. Not sure if that will work for anybody else, but just thought I’d throw this out there (problem happened after the Monday update from MS Update).

Solution 6
I was getting the same error message. But used the click here underlined for details. Stated the problem was with the uxtheme.dll file. So from msconfig, I uncheck the theme services. Rebooted with no errors. Realized that it turned off my XP Theme. So went into Services from Admin Tools, and set disable to automatic and click the Start button, to start the service. Then rebooted. Have not received the error since.

UXTheme is the XP Theme package, but was recently updated in a patch. So maybe chalk it up as a bad install. Now repaired.

Another option is to go to c:\windows\system32 and find the uxtheme.dll file. Rename it to uxtheme.dll.old. Then restart. Should repair, reinstall itself.

Problem 2: Stop 0x000000B4 The Video Driver Failed to Initialize
After doing Chkdsk command, I was getting the blue screen. After this stage, I didn't get Winlogon.exe - Application Error. I did Google search for this system error and I got few solutions for that.

Solution 7
From forums.techguy.org
It may be the built in VGA driver is corrupt. You could try replacing it in Recovery Console from the CD. I've attached a screen shot of the commands.

To do this boot into the Recovery Console. This should leave you at a C:\Windows prompt. Enter the following commands:

cd system32
ren vga.dll vga.dllold
ren vga.drv vga.drvold
cd drivers
ren vga.sys vga.sysold
expand d:\i386\vga.sy_
cd ..
expand d:\i386\vga.dl_
expand d:\i386\vga.dr_


Exit, and then try Safe Mode and/or Enable VGA Mode.

Solution 8
From forums.cnet.com
To anyone with this same problem - here's how I recovered my files:

Changed my Bios to boot from Windows XP DVD-ROM.
Installed XP to the SAME PARTITION as my corrupt one, only I created a new folder entitled XP_2.
It did get stuck once on the "34-min left" but I just re-tried and it worked the second time.
When it was done installing, it asked me for an account name - DO NOT NAME THE PROFILE ACCOUNT THE SAME AS ANY OF YOUR ALREADY EXISTING ACCOUNTS. I made a generic account name.
When it was done installing, go into your hard drive, documents and settings and voila! There you will see your other user accounts along with their desktops and my document folders. Also, you will be able to see your Program Files and any other hard drive folders you need.

Solution 9
One other thing Microsoft help says may cause the B4 STOP is a port conflict. If your laptop has a parallel port, disable in BIOS or change I/O address to 0378 from 03BC.

Solution 10 - From Microsoft Knowledge base
Solution - STOP: 0x000000B4 The video driver failed to initialize.
Solution - STOP: 0x000000B4 The video driver failed to initialize
SYMPTOMS
When you try to start Windows 2000, you may receive the following error message (on a blue screen):
*** STOP: 0x000000B4
The video driver failed to initialize.

Additionally, you cannot start Windows in Safe mode.

Solution 11 - Virus Infection
None of these solutions were worked for me. microsoft.public.windowsxp.customize. I got a idea from this post. I did following steps.

  • Removed the hard-disk from my PC.

  • Have connected the my PC through external drive to my Laptop. Both systems are having Windows XP SP2

  • Ran the anti-virus program for G drive, which is C Drive for my home PC.

  • 2 DLLs (under C:\Windows\System32) got infected. Removed those files.

  • Deleted 2 files under C:\Windows\System32, which are created on that day (based on the time-stamp).

  • Connected the hard-disk to my home PC again. Started my PC through WinXP setup CD.

  • Automatically Upgrade workstation was executed from Windows CD (Repair Windows Installation).

  • Rebooted System successfully and did not get any system errors..

Sunday, September 28, 2008

Children objects has negative co-ordinates in Browserchild

Last year, one web based product has been revamped with our own reporting modules. Lot of javascripts used for this reporting. Silktest is able to identify the HtmlTable and HtmlColumn objects properly. But the co-ordinates are shown wrong. Each click action is done in different point instead of expected point. Only X-Axis position got changed. See the RECT info below.

BrowserChild (Parent) rect: {195, 175, 827, 538}
Htmltable rect: {-77, 323, 818, 574}


It is varying for different kind of reports. Testcases need to do left-mouse click and right-mouse clicks. I have set few variables for position changes. I have written the code like below. In the Runtime, XAxis changes (ixGridInc) are calculated dynamically. I have given the code below:

4Test code - To set the Table position dynamically


[-] void SetGridTablePosChanges (Window wTable)
[ ] // To set xAxis and YAxis increments (changes)
[ ] // Position changes.
[ ] Window wParent
[ ] Boolean bxGetPos = FALSE
[ ] String sWinTag, sMainFrameTag
[ ]
[ ] RECT rtTblCell = wTable.GetRect (TRUE)
[ ] Print ("table rect: {rtTblCell}")
[ ]
[-] if (ixGridInc == -1)
[ ] Print ("Grid xAxis increment is going to set.")
[ ] ixGridPos = rtTblCell.xPos
[ ] // iyGridPos = rtTblCell.yPos
[ ] bxGetPos = TRUE
[-] else if (ixGridPos != rtTblCell.xPos)
[ ] bxGetPos = TRUE
[ ] ixGridPos = rtTblCell.xPos
[ ] // iyGridPos = rtTblCell.yPos
[-] else
[ ] Print ("Already Grid xAxis increment is available.")
[ ]
[-] if (bxGetPos)
[ ]
[ ] sMainFrameTag = WindowTag (wTable)
[ ] sWinTag = GetField (sMainFrameTag,"[BrowserChild]",3)
[ ] Print ("Whole Table tag: {sMainFrameTag}")
[ ] Print ("Parent tag: {sWinTag}")
[-] if (MatchStr ("*[6]*",sWinTag) || MatchStr ("*mainFram*",sWinTag))
[ ] wParent = MyReportPage
[ ] RECT rtTblCell2 = wParent.GetRect (TRUE)
[ ] Print ("Parent rect: {rtTblCell2}")
[ ]
[-] if ((rtTblCell.xPos < (rtTblCell2.xPos + XAXIS_TABLE_DIFF)) )
[ ] ixGridInc = rtTblCell2.xPos - (rtTblCell.xPos) + XAXIS_TABLE_DIFF
[ ] Print ("X Axis changed Position: {ixGridInc}")
[-] else
[ ] Print ("Parent{wParent} is not expected one.")

Tuesday, September 16, 2008

Automating Windows/Unix/Linux Server calls by w3Sockets

Earlier I have written a post Expect-Automating Command line tools for Expect utility. Now we can access any server machines by using VBScript. Dimac Development has implemented a COM interface to connect through Telnet and made as freeware. You need to download w3Sockets Dll and register it using SocketReg.exe included in a zip file. It is similar to expect utility. You can verify each command and can change the execution flow based on console output. It is much useful for automated testing as well as server administration. Below I have given a sample code to start windows services.

w3Sockets Reference
w3Sockets - Download Page

To start servers on Windows/Unix/Linux Systems



'To start servers on Windows/Unix/Linux server
Dim w3sock

Set w3sock = CreateObject("socket.tcp")
With w3sock
.timeout = 5000
.DoTelnetEmulation = True
.TelnetEmulation = "TTY"
.Host = "myserver:23"
.Open
.WaitFor "login:"
WScript.Echo .Buffer
.SendLine "myloginid"
.WaitFor "password:"
.SendLine "Password12"
.WaitFor ">"
.SendLine "net start ""MyServer Manager"""
.WaitFor ">"
WScript.Echo .Buffer
.SendLine "net start ""MYDB Repository"""
.WaitFor ">"
WScript.Echo .Buffer
.Close
End With
Set w3sock = Nothing

Saturday, September 13, 2008

Lightweight Directory Access Protocol

Last few months, I'm trying to put a post for LDAP. Now LDAP is widely used in many companies. LDAP Testing is bit different from (native mode) user authentication. Again It is divided as single domain and multi-domain LDAP. Test team is treating LDAP as a another environment/stack to certify any product.

LDAP - Lightweight Directory Access Protocol. LDAP has become a mandatory in IT Projects. It is a set of protocols for accessing information directories. LDAP is based on the standards contained within the X.500 standard, but is significantly simpler. Also unlike X.500, LDAP supports TCP/IP, which is necessary for any type of Internet access.

The LDAP Interchange Format (LDIF), defined in RFC 2849, is a standard text file format for storing LDAP configuration information and directory contents. The dn attribute uniquely identifies the DN of the entry. In its most basic form, an LDIF file is:

  • A collection of entries separated from each other by blank lines

  • A mapping of attribute names to values

  • A collection of directives that instruct the parser how to process the information


Descriptions for commonly used abbreviations:
  • cn - Common Name

  • ou - Organizational Unit

  • dc - Domain Component

  • dn - Distinguished Name

  • rdn - Relative Distinguished Name

  • upn - User Principal Name


Sample LDAP configuration:
Principal : cn=admin,cn=Users,DC=rmdomain,DC=com
Users baseDN : DC=rmdomain,DC=com
Group baseDN : DC=rmdomain,DC=com
Bind User DN : cn=admin,cn=users,dc=rmdomain,dc=com

To know more about LDAP

Wiki - Lightweight Directory Access Protocol
LDAP Concepts & Overview
LDAP Authentication

Saturday, September 6, 2008

Saving Clipboard contents as Image

Scenario 1:
Earlier I had a challenging task to automate SVG charts. There are two issues. Major issue is, Silktest does not identify SVG Chart as any object (custom/HtmlImage). Second one is taking Bitmap image for the chart. SVG chart gives the flexibility by 'Copy SVG' feature. Using this we can copy the chart image. It can be saved as text or Image file.

Scenario 2:
Last month, I have posted VBA - Extract Pictures from Excel . It works fine, if this VBA code is executed as Excel Macro. But the same code does not extract the image with the right quality, after running as VB Script. I got the problem, while saving/pasting the clipboard copy. I was forced to find a way to implement a method, to save clipboard image as a image file.

Solution:
IrfanView is a windows graphic viewer and it is a freeware utility. It can be used command-line utility. It has a command-line option to save the clipboard image as image file. You can save the image in many different formats.

Syntax to Convert clipboard image as image file:
/clippaste - paste image from the clipboard.

Below I have given the way to implement in VBScript and Silktest.
Silktest code:


[ ] // To save the image
[ ] SYS_Execute ("D:\autostuff\i_view32.exe /silent /clippaste /convert=D:\my_scripts\testdata\zsvg1.bmp")


VB Script code:

'-------------------------------------------------------------------------
' Method : CreateImageFromClipBoard
' Author : Palani Selvam
' Purpose : It gets the clipboard image and convert as a image file.
' Parameters: FileName - String, contains the BMP file name
' iIndex - Integer, contains the Worksheet index
' Returns : String. The replaced file name it gives.
' Caller : - Nil
' Calls : - Nil
'-------------------------------------------------------------------------
Sub CreateImageFromClipBoard(sFileName)

Dim wshShell,ShellReturnCode, sCmdExec

Set WshShell = WScript.CreateObject("WScript.Shell")
sCmdExec = "D:\autostuff\i_view32.exe /silent /clippaste /convert="& sFileName

ShellReturnCode = WshShell.Run(sCmdExec, 1, True)

End Sub


Modified VB Script code for VBA - Extract Pictures from Excel
Note: Few function calls are from my vbscript library.

'--------------------------------------
' Method : ReadExcel
' Author : T. Palani Selvam
' Purpose : Read all the contents from Excel sheet and write into log file
' Parameters: sExcelFile - String, contains the Excel file
' : iSheetIndex - Integer, Value for Sheet Index
' Returns : - Nil
' Caller : - Nil
' Calls : - Nil
'--------------------------------------
Sub ReadExcel(sExcelFile, iSheetIndex)
Dim sExcelPath 'As Variant 'Excel file
'********** Excel object declaration **********'
' Excel Application object
Dim objExcel 'As Excel.Application
Dim objXLWorkbooks 'As Excel.Workbooks
Dim objXLWorkbook 'As Excel.Workbook

Dim WorkSheetCount 'As Variant 'Work sheets count in a excel
Dim CurrentWorkSheet 'As Excel.Worksheet ' Current worksheet
Dim objCells 'As Excel.Range
Dim objCurrentCell 'As Variant
Dim objFont 'As Variant

' Result contents
Dim sCellText 'As Variant
Dim sFontName 'As Variant
Dim sFontStyle 'As Variant
Dim iFontSize 'As Variant
Dim iCellTextColorIndex 'As Variant
Dim iCellInteriorColorIndex 'As Variant
Dim sResult 'As Variant
Dim sChartFile 'As String


' Row and Col integer variables
Dim iUsedRowsCount 'As Integer
Dim iUsedColsCount 'As Integer
Dim iTop, iLeft 'As Integer
Dim iRow 'As Integer 'Row item
Dim iCol 'As Integer 'Col item
Dim iCurRow 'As Integer
Dim iCurCol 'As Integer


If (sExcelFile = "") Then
sExcelPath = "D:\my_scripts\Basic Wks.xls"
Else
sExcelPath = sExcelFile
End If

If (iSheetIndex = "") Then
iSheetIndex = 2
End If


Call FileDeleteAndCreate (gsLogFile)

'XL file check
If (FileExists(sExcelPath) <> 0) Then
Call LogWrite (gsLogFile, "The Excel file " & Chr(34) & sExcelPath & Chr(34) & " does not exit!")
Exit sub
End If

Set objExcel = CreateObject("Excel.Application")
objExcel.Workbooks.Open sExcelPath, False, True

On Error Resume Next

Set objXLWorkbook = objExcel.ActiveWorkbook
'objXLWorkbook.RunAutoMacros

WorkSheetCount = objXLWorkbook.Worksheets.Count

Set CurrentWorkSheet = objExcel.ActiveWorkbook.Worksheets(iSheetIndex) 'iSheetIndex worksheet

iUsedRowsCount = CurrentWorkSheet.UsedRange.Rows.Count
iUsedColsCount = CurrentWorkSheet.UsedRange.Columns.Count
iTop = CurrentWorkSheet.UsedRange.Row
iLeft = CurrentWorkSheet.UsedRange.Column

' Cells object
CurrentWorkSheet.Cells.Activate


For iRow = iTop To iUsedRowsCount-1 '(iUsedRowsCount - 1)
'Read All rows
For iCol = iLeft To iUsedColsCount '(iUsedColsCount - 1)

sResult = ""
Set objCurrentCell = CurrentWorkSheet.Cells(iRow, iCol)
sCellText = objCurrentCell.Text


If ((sCellText = Empty)) Then


sResult = "Reading Cell {" & CStr(iRow) & ", " & CStr(iCol) & "}^" &" "& "^" & " " & "^" & " " & "^" & " " & "^" & " " & "^" & " "

Call LogWrite (gsLogFile, sResult)

Else
Set objFont = objCurrentCell.Font
sFontName = objFont.Name
sFontStyle = objFont.FontStyle
iFontSize = objFont.Size
iCellTextColorIndex = objFont.Color
iCellInteriorColorIndex = objCurrentCell.Interior.ColorIndex



If (sFontName = Empty) Then
sFontName = "empty"
End If
If (sFontStyle = Empty) Then
sFontStyle = "empty"
End If
If (iFontSize = Empty) Then
iFontSize = "-99999999"
End If
If (iCellTextColorIndex = Empty) Then
iCellTextColorIndex = "99999999"
End If
If (iCellInteriorColorIndex = Empty) Then
iCellInteriorColorIndex = "99999999"
End If


sResult = "Reading Cell {" & CStr(iRow) & ", " & CStr(iCol) & "}^" & sCellText & "^" & CStr(iCellInteriorColorIndex) & "^" & sFontName & "^" & CStr(sFontStyle) & "^" & CStr(iFontSize) & "^" & CStr(iCellTextColorIndex)

Call LogWrite (gsLogFile, sResult)

End If

Set objCurrentCell = Nothing


Next

Next
'Get the Chart now
'sChartFile = Replace (sExcelFile,".xls",".png")
sChartFile = Replace (sExcelFile,".xls",".bmp")

'*****************************
' Place for Chart creation
objExcel.ScreenUpdating = False

Dim iIndex,iPictureHeight,iPictureWidth,iShapeCount
Dim aShape, aChart, aShapeChart, aChart1
Dim sPictureShape, sChartName, sCurrentSheet


'Set aWorkSheet = ActiveWorkbook.ActiveSheet

sCurrentSheet = CurrentWorkSheet.Name

For iIndex = 1 To CurrentWorkSheet.Shapes.Count

Set aShape = CurrentWorkSheet.Shapes(iIndex)
sPictureShape = aShape.Name
'Picture 1 Name, 13

If Left(aShape.Name, 7) = "Picture" Then
aShape.CopyPicture
Call CreateImageFromClipBoard (sChartFile)

''objExcel.ScreenUpdating = True
Exit For

End If
Next

if FileExists(sChartFile)=0 Then
Call LogWrite (gsLogFile, "Chart Image: " & sChartFile)
End If

' This will prevent Excel from prompting us to save the workbook.
objExcel.ActiveWorkbook.Saved = True
Set CurrentWorkSheet = Nothing

'objExcel.Worksbooks.Close
objExcel.Quit

''Set CurrentWorkSheet = Nothing
Set objExcel = Nothing

'MsgBox "Read Completed.", vbOKOnly, "Exec Over"
Exit Sub

ErrorHandler1:
'MsgBox "Error # " & CStr(Err.Number) & " " & Err.Description
'Err.Clear ' Clear the error.
End Sub

Wednesday, September 3, 2008

Convert failed testcases as a testplan

We have few silktest automation projects. One project is used to execute by suite. Another one is ran by batch (*.bat) file, which has few sub-plans. I am not able to run the failed cases from all results at one shot. I was looking an utility, similar to 'Mark failures in Plan' in the results menu. I thought to implement a 4test script to convert failed testcases as a testplan and I did it.

4Test code - Create testplan for failed cases only

[ ] LIST OF STRING glsFailedScripts = {} [ ] [+] testcase ConvertTestPlan_SingleFile () appstate none [ ] [ ] STRING sResFile = "D:\Auto_Scripts\Results\MyStuff_MasterPlan.res " [ ] STRING sRexFile = "D:\Auto_Scripts\Results\MyStuff_MasterPlan1.rex " [ ] STRING sMyPlanFile = "D:\Auto_Scripts\Results\zSingleFailed.pln " [ ] [ ] glsFailedScripts = {} [ ] CreateFileFromTemplate(sPlanTemplate,sMyPlanFile) [ ] ResExport (sResFile,sRexFile) [ ] ProcessSingleREXFile (sRexFile,sMyPlanFile) [ ] [ ] Agent.DisplayMessage ("test","Completed.") [ ] [-] // functions [+] Boolean GetFailedTestInfo (STRING sRexLine, out LIST OF STRING lsPlanInfo) [ ] [ ] // Title [ ] //TestPlan Script TestCase TestData ErrorCount ErrorText DateTime Elapsed [ ] [ ] // Samples [ ] // "D:\Auto_Scripts\PlanFiles\MyStuff_MasterPlan.pln","D:\Auto_Scripts\Scripts\FamilyFunctions.t","FamilyFunctions_DimensionFunctions_5", [ ] // "Verify user sees a proper error message by clicking OK button.",0,"","2008-08-18 21.52.06","0:00:00" [ ] [ ] STRING sScript [ ] STRING sTestCase [ ] STRING sTestData,sFormattedData [ ] STRING sTestTime [ ] STRING sErrCount, sErrCount1 [ ] INTEGER iPos [ ] [ ] // Initialization [ ] STRING sIndentation = " " [ ] STRING sIndentation1 = "[+] " // Level1 [ ] STRING sIndentation2 = " [ ] " // Level2 [ ] [ ] STRING sSeperator = """,""" [ ] STRING sErrSeperator = ",""" //",""***" [ ] STRING sDataSeperator = """,0,""" [ ] STRING sErrSeperator1 = """" [ ] Boolean bResult = FALSE [ ] lsPlanInfo = {} [ ] [ ] sErrCount1 = GetField (sRexLine,sSeperator,4) [ ] sErrCount = GetField (sRexLine,sDataSeperator, 2) [ ] //if ((Trim(sErrCount) != "") && (Val(sErrCount) > 0)) [+] if ((Trim(sErrCount) == "") && (Trim(sErrCount1) != "") ) [ ] Print ("Considering line: {sRexLine}") [ ] bResult = TRUE [ ] sScript = GetField (sRexLine,sSeperator,2) [ ] sTestCase = GetField (sRexLine,sSeperator,3) [ ] sTestTime = GetField (sRexLine,sSeperator,6) [ ] Print ("Elapsed: {sTestTime}") [+] if (sTestTime == "") [+] sFormattedData = "" [ ] iPos = StrPos (sErrSeperator, sTestCase,TRUE) [+] if (iPos > 0) [ ] Print ("sTestCase:{sTestCase}: iPos:{iPos}") [ ] sTestCase = SubStr (sTestCase, 1,iPos - 4) [ ] Print ("Before formatting, sTestCase:{sTestCase}") [ ] //sTestCase = StrTran (sTestCase,"\","") [ ] Print ("After formatting, sTestCase:{sTestCase}") [ ] [+] else [ ] sTestData = GetField (sRexLine,sSeperator,4) [+] if (MatchStr ("*,?,""*",sTestData)) [ ] iPos = StrPos (sErrSeperator, sTestData,TRUE) [+] if (iPos > 0) [ ] Print ("TestData:{sTestData}: iPos:{iPos}") [ ] sTestData = SubStr (sTestData, 1,iPos - 4) [ ] Print ("Before formatting, TestData:{sTestData}") [ ] sFormattedData = StrTran (sTestData,"\","") [ ] Print ("After formatting, TestData:{sTestData}") [ ] [ ] Print ("TestCase: {sTestCase}") [ ] Print ("TestData: {sFormattedData}") [ ] [+] if ( (glsFailedScripts == {}) || (glsFailedScripts[ListCount(glsFailedScripts)] != sScript) ) [ ] ListAppend (glsFailedScripts,sScript) [ ] ListAppend (lsPlanInfo,"{sIndentation1}#script: {sScript}") [+] // if (Trim (sTestData) != "") [ ] // ListAppend (lsPlanInfo,"{sIndentation2}#testdata: {sFormattedData}") [ ] ListAppend (lsPlanInfo,"{sIndentation2}#testcase: {sTestCase}({sFormattedData})") [ ] [+] else [ ] Print ("Not Considering line: {sRexLine}") [ ] [ ] return bResult [+] public void TestPlanWrite(STRING sPlanFile, ANYTYPE aMsg) [ ] // To write content into log file [ ] HFILE hFile [ ] STRING sItem [ ] [ ] hFile = FileOpen (sPlanFile, FM_APPEND) [+] switch TypeOf (aMsg) [+] case STRING [ ] FileWriteLine(hFile,"{aMsg}") [+] case LIST OF STRING [+] for each sItem in aMsg [ ] FileWriteLine(hFile,"{sItem}") [+] default [ ] Print ("Non supported element for TestPlanWrite: {TypeOf (aMsg)}") [ ] FileWriteLine(hFile,"{aMsg}") [ ] [ ] FileClose (hFile) [ ] [ ] [+] VOID ProcessSingleREXFile (String sRexFile, STRING sPlanFile) [ ] // To create a testplan [ ] // Implemented for Auto Scripts [ ] // It will read the text file [ ] [+] // Parsing REX file and then writing into plan file [ ] HFILE hInFile [ ] STRING sLine [ ] LIST OF STRING lsPlan [ ] [ ] hInFile = FileOpen (sRexFile,FM_READ) [ ] [+] while (FileReadLine (hInFile, sLine)) [+] if (GetFailedTestInfo (sLine,lsPlan)) [ ] TestPlanWrite (sPlanFile,lsPlan) [ ] [ ] FileClose (hInFile)

Saturday, August 30, 2008

Converting Bitmap to GIF/JPG image

Earlier I have written a post about Automation Basics - Capturing Failures . Almost all the GUI testing tools are providing built-in functions to take the snapshot of screen. Snapshot can be taken for given screen co-ordinates or entire object.

Mostly these snapshots are stored as bitmap (*.bmp) files. Bitmap files are occupying more hard-disk space. It is difficult to maintain all the snapshots for each build in release-wise. IrfanView is a windows graphic viewer and it is a freeware utility. It has many command-line options for image related actions. You can just copy the executable file to another machine and can open or use immediately.

Syntax to Convert one image to another image format:
/convert=filename - convert input file to 'filename' and close IrfanView

Below I have given the way to implement in Silktest. This can be done for any testing tool.



[ ] //convert the image
[ ] SYS_Execute ("D:\autostuff\i_view32.exe {sBmpImage} /silent /convert={sGifImage}")

Wednesday, August 27, 2008

Restart Silktest Agent at Runtime

Last few months, I faced one issue and solved it by restarting silktest Agent.
Problem
We have a silktest suite for our Excel AddIn. It is developed by DotNet Framework. Silktest DotNet extension goes off after running 75-200 tests. Also facing this issue differently for both Excel 2003 and Excel 2007. Already I raised one post 'Application not responding" for this.



[ ] *** Error: Application is not responding
[ ] Occurred in Exists
[ ] Called from MSExcelAddIns at ExcelRecoverySystem.inc(573)
[ ] Called from ASCS_EAIBaseState at ExcelRecoverySystem.inc(684)
[ ] Called from SymmetricReport at ExcelRecoverySystem.inc(714)
[ ] Called from TestcaseEnter at ExcelRecoverySystem.inc(255)
[ ] Called from PreservingFunctions_ReplaceWithUpper at PreservingFunctions.t(238)
[ ] Error E_APP_NOT_RESPONDING) raised. Closing all applications
[ ] *** Error: Application is not responding
[ ] Occurred in Exists
[ ] Called from KillExcelApp at ExcelRecoverySystem.inc(395)
[ ] Called from CloseAllApps at ExcelRecoverySystem.inc(386)



Solution:
Later selected cases are executed fine, If I close silktest agent and re-run few cases. I am able to figure out, where/when it is not able to identify. Then I tried to restart the agent in that machine, while scripts are executing continuously.

4Test code: To restart Silktest Agent


[-] void RestartSilkAgent ()
[ ] // To Restart Silktest Agent
[ ]
[ ] STRING sAgent
[ ]
[ ]
[ ] sAgent = GetMachineName ()
[ ] Print ("Agent name: {sAgent}")
[ ] Print (Desktop.GetActive ())
[ ] Disconnect (sAgent)
[ ]
[ ] Print ("**** Restarting Silktest Agent ...")
[ ] SYS_Execute ("D:\SampleDotNet\RestartAgent.bat")
[ ] Print ("**** Restarted Silktest Agent @@@@@@")
[ ]
[ ] Connect (sAgent)
[ ] Print (Desktop.GetActive ())
[ ]
[ ]

Friday, August 22, 2008

VBA - Extract Pictures from Excel

Last month, I have written Excel Automation Using VBScript. Today this post is to extract Pictures from Excel. Generally We can not use Export method for pictures. But we can use for Excel charts. I tried to extract our SVG chart image by macro and I succeed on it. I got help from Export pictures from Excel Below I've given the VBA Macro code.

VBA Macro - To extract Picture from Excel

Sub GetFirstPicture() Dim sCurrPath As String Dim aWorkSheet As Excel.Worksheet Dim aShape As Excel.Shape Dim aShapeChart As Excel.Shape Dim aPicture As Variant Dim aChart As Excel.Chart Dim sCurrentSheet As String Dim aImage As Variant Dim iIndex As Integer Dim iShapeCount As Integer Dim MyChart As String, MyPicture As String Dim PicWidth As Long, PicHeight As Long Dim sChartJpg As String Dim sChartGif As String Dim sChartBmp As String 'On Error GoTo ErrHandler On Error Resume Next Application.ScreenUpdating = False sCurrPath = "D:\VB\MyTrials\ChartExpFromXL" sChartJpg = "D:\VB\MyTrials\ChartExpFromXL.jpg" sChartGif = "D:\VB\MyTrials\ChartExpFromXL.gif" sChartBmp = "D:\VB\MyTrials\ChartExpFromXL.bmp" Set aWorkSheet = ActiveWorkbook.ActiveSheet sCurrentSheet = aWorkSheet.Name 'MsgBox CStr(msoTrue) + " value for MsoTrue" ' MsoTrue equals to -1 MsgBox "Shapes count " + CStr(aWorkSheet.Shapes.Count) For iIndex = 1 To aWorkSheet.Shapes.Count Set aShape = aWorkSheet.Shapes(iIndex) MyPicture = aShape.Name MsgBox aShape.Name + " Name, " + Str(aShape.Type) 'Picture 1 Name, 13 If Left(aShape.Name, 7) = "Picture" Then With aShape PicHeight = .Height PicWidth = .Width End With 'Set aChart = aWorkSheet.ChartObjects(1) Set aChart = ActiveWorkbook.Charts.Add ActiveWorkbook.ActiveChart.Location Where:=xlLocationAsObject, Name:=sCurrentSheet iShapeCount = aWorkSheet.Shapes.Count Set aShapeChart = aWorkSheet.Shapes(iShapeCount) MyChart = aShapeChart.Name '"Chart " & Str(aWorkSheet.Shapes.Count) aShapeChart.Width = PicWidth aShapeChart.Height = PicHeight With aWorkSheet aShape.Copy With ActiveChart 'aChart .ChartArea.Select .Paste End With .ChartObjects(1).Chart.Export Filename:=sChartJpg, FilterName:="jpg", Interactive:=True .ChartObjects(1).Chart.Export Filename:=sChartGif .ChartObjects(1).Chart.Export Filename:=sCurrPath & ".png" 'Not working .ChartObjects(1).Chart.Export Filename:=sChartBmp, FilterName:="bmp" aShapeChart.Cut End With Application.ScreenUpdating = True MsgBox "Completed." Exit Sub End If Next MsgBox "Completed." Exit Sub ErrHandler: MsgBox "Error # " & CStr(Err.Number) & " " & Err.Description & " " & Err.Source Err.Clear ' Clear the error. End Sub

Sunday, August 17, 2008

Comparison between 4Test and C language Keywords

Few months back, I was going through 4Test Language Reference (Silktest 5.01) PDF document. There I have seen the comparison of C Language and 4Test. Then I searched the same table in Silktest8.5 Help documentation. It is available under 4Test Reference -> About the 4Test Language -> Comparison of 4Test and C.

Comparison Table: 4Test and C language Keywords

Data type / Feature

C Language

4Test Script

Any type: Stores data of any typeNo datatype available.ANYTYPE aName
Array int ai[10];
  • array [10] of integer ai
  • integer ai[10]
  • Arrays in 4Test can be dynamically resized.
Boolean: Stores either TRUE or FALSEint b;boolean b
Characterchar c;string c. 4Test has no seperate data type for single character.
Enumeratedenum COLOR{red, white, blue};type COLOR is enum red white blue
Floating-point float f; double d;
  • real f
  • real d
Integerint i; long, short, unsignedinteger i
ListSimilar datatype is not available.list of integer li. 4Test has dynamic lists.
NumericSimilar datatype is not available.number n.4Test NUMBER type stores either integers or floating point numbers.
Pointerchar *p; 4Test does not have pointers; however, data can be indirectly referenced using the @ operator.
Pointer to function int (*func) (); @(sFunc) ()
Stringchar s[5]; STRING s. 4Test strings are dynamically allocated; you do not need to declare their lengths.
Structure struct Person { char name[8]; int age; } type Person is record { string name integer age}
User-defined type typedef struct Person PERSON_INFO;type PERSON_INFO is Person
Type cast operator (typename) expression [typename] expression
Equality (==) operator differences if ((i=5) == TRUE) --> This code compiles in C if ((i=5) == TRUE) --> Ths code does not compile in 4Test:This difference is intentional. Because this construct can lead to unreadable code, 4Test does not allow it.

Friday, August 15, 2008

SilkTest - Convert String to List of String

Last month, my friend asked a silktest function similar to Split in QTP. Silktest does not have any built-in function. I thought to develop a function for this need. See the 4test code below:

4Test Code - Convert STRING contents as List of STRING

[+] List of STRING SplitToList (String sInput, String sDelimiter) [ ] List of STRING lsReturn = {} [ ] Integer iIndex =1 [ ] [+] while (GetField (sInput,sDelimiter,iIndex) != "") [ ] ListAppend (lsReturn, GetField (sInput,sDelimiter,iIndex)) [ ] iIndex++ [ ] [ ] return lsReturn

Sunday, August 10, 2008

Re-using VBS code

Last week, I wanted to call VBS file into another VBS file. I wanted similar way in other languages like below.
In C++ -> Header file -> include <*.h>
In VB -> Modules (*.bas)
In Java -> Packages -> import com.myLayer.*


Basically I wanted to make it as a library. I am writing the functions to get the data from Excel and PPT. I have to create separate VBS file for each requirement. Few functions are common for all the VBS files. I got a help from visualbasicscript site. Post: Include VBS file in other files

VBScript code - To Import VBS Library



'--------------------------------------
' Method : ImportVBSLibrary
' Author : T. Palani Selvam
' Purpose : To import all vbs code from library file.
' Parameters: sFileName - String, contains the VBS functions
' Returns : VBS code
' Caller : - Nil
' Calls : - Nil
'--------------------------------------
Function ImportVBSLibrary(sFileName)
Dim ObjFSO,ObjFile
Set ObjFSO = CreateObject("Scripting.FileSystemObject")
Set ObjFile=ObjFSO.OpenTextFile(sFilename,1)
ImportVBSLibrary=ObjFile.ReadAll
Set ObjFile = Nothing
Set ObjFSO = Nothing
End Function

ExecuteGlobal ImportVBSLibrary("D:\myscripts\tools\pal_lib.vbs")


Friday, August 8, 2008

VBScript - Numbers as CmdLine Arguments

While I was preparing code for Excel Automation , I decided to pass the few integer values. Always the script got failed, if I pass the integer values through arguments. But the script went through fine, if I directly pass the parameters in that function call. While debugging the code, I was not able to find the reason for failure. I did Google search and unable to get the right solution.

Later I analyzed the code and put the simple conversion, while getting the arguments. The code worked as expected.


  1. To Convert String to Integer --> iStartRow = CInt (WScript.Arguments.Item(1))

  2. To Convert String to Double --> dExpVal = CDbl (WScript.Arguments.Item(2))

  3. To Convert String to Number --> nRowRange = Val (WScript.Arguments.Item (3))

To know more about the Command Line Arguments to VBScript, go through this post - Passing Command Line Arguments .

If you are unable to run any VBScript, See my old post - Unable to run VBScript / WScript / CScript in Windows XP .

Sunday, August 3, 2008

Silktest - Date Puzzle

I am always interested to participate in code competition. Recently I solved one puzzle like that.

Puzzle
Develop an algorithm to display the day of the week (Sunday to Saturday) for a given date. For example, if the date given is 07/07/2008 (8th July 2008, dd/mm/yyyy format), the algorithm would return Monday. Date 29/02/2008 will return Friday.

Solution - 4test code

[+] testcase Puzzle_4Test (STRING sGivenDate) appstate none [ ] // Puzzle: [ ] // Develop an alogrithm to display the day of the week (Sunday to Saturday) for a given date. [ ] // For example, if the date given is 07/07/2008 (8th July 2008, dd/mm/yyyy format), the algorithm would return Monday. [ ] // Date 29/02/2008 will return Friday. [ ] INTEGER iGivenYear, iGivenMonth, iGivenDay [ ] DATETIME dtFormat [ ] STRING sResult [ ] [ ] STRING sSeperator = "/" [ ] STRING sFormatRequired = "dddd" // To get the day in word [ ] [+] do [ ] [ ] iGivenDay = Val (GetField (sGivenDate,sSeperator,1)) [ ] iGivenMonth = Val (GetField (sGivenDate,sSeperator,2)) [ ] iGivenYear = Val (GetField (sGivenDate,sSeperator,3)) [ ] [ ] dtFormat = MakeDateTime (iGivenYear,iGivenMonth, iGivenDay) [ ] sResult = FormatDateTime (dtFormat,sFormatRequired) [ ] Print ("Puzzle1: Input - {sGivenDate}: Result - {sResult}") [+] except [ ] LogError ("Puzzle1: Input - {sGivenDate} is not in expected Format dd/mm/yyyy")

Thursday, July 31, 2008

VisualTest - Browser related functions

VisualTest has different set of functions for browser related operations. Below I have given few code snippets.

VistualTest code - To Invoke Internet Explorer

'--------------------------- ' Method : WebStart ' Author : T.Palani Selvam ' Purpose : To Start a IE. ' Parameters: sURL As String. ' ' Returns : - Nil - ' Caller : - Nil ' Calls : - Nil - '----------------------------- Sub WebStart(sURL As String) gsContext = WebExplore(sURL) WSetActWnd(val(gsContext)) If Not wIsMaximized(val(gsContext)) Then wMaxWnd(val(gsContext)) Sleep giPageLoad Logwrite("IE is started. URL : " + sURL , 1) End Sub

Vistual Test code - Navigate to given URL
'------------------------ ' Method : WebNavigation ' Author : T.Palani Selvam ' Purpose : To Start a IE. ' Parameters: sURL As String. ' ' Returns : - Nil - ' Caller : - Nil ' Calls : - Nil - '--------------------------- Sub WebNavigation(sURL As String) If ( Not WebBrowserExists(gsContext)) Then WebStart(sURL) Else WebNavigate(gsContext, sURL) Sleep giPageLoad WSetActWnd(val(gsContext)) If Not wIsMaximized(val(gsContext)) Then wMaxWnd(val(gsContext)) Logwrite("Navigated URL : " + sURL , 1) End If End Sub

Vistual Test code - To click Back Button in Browser
'-------------------------- ' Method : WebBackHistory ' Author : T.Palani Selvam ' Purpose : Back history from IE. ' Parameters: sValue As String. ' ' Returns : - Nil - ' Caller : - Nil ' Calls : - Nil - '----------------------------- Sub WebBackHistory(sValue As String) Dim iTimes As Integer iTimes = Val(sValue) If ( Not WebBrowserExists(gsContext)) Then LogWrite("Main Browser doesn't exist.Couldn't be gone to back", 1) Else If (iTimes = 0) Then iTimes = 1 WebBack(gsContext, iTimes) Sleep giPageLoad WSetActWnd(val(gsContext)) If Not wIsMaximized(val(gsContext)) Then wMaxWnd(val(gsContext)) Logwrite("Going back number of items in History is " + str(iTimes) , 1) End If End Sub

Vistual Test code - To click Forward Button in Browser
'--------------------------- ' Method : WebForwardHistory ' Author : T.Palani Selvam ' Purpose : Forward history from IE. ' Parameters: sValue As String. ' ' Returns : - Nil - ' Caller : - Nil ' Calls : - Nil - '--------------------------------- Sub WebForwardHistory(sValue As String) Dim iTimes As Integer iTimes = Val(sValue) If ( Not WebBrowserExists(gsContext)) Then LogWrite("Main Browser doesn't exist.Couldn't be gone to Forward", 1) Else If (iTimes = 0) Then iTimes = 1 WebForward(gsContext, iTimes) Sleep giPageLoad WSetActWnd(val(gsContext)) If Not wIsMaximized(val(gsContext)) Then wMaxWnd(val(gsContext)) Logwrite("Going Forward number of items in History is " + str(iTimes) , 1) End If End Sub

Friday, July 25, 2008

Silktest - TestPlan solutions

TestPlan is one of the good features in Silktest. You can query to execute certain testcases from Testplan. Also you can mark only failures from the silktest results. Below I have given the two test plan issues and solutions for them.

1. How to pass Dollar ($) sign in TestPlan?
TestPlan is using $ symbol to represent the variables. Silktest will through the error, if any testdata contains dollar ($) character explicitly.
Solution:
Replace symbol $ by {Chr(36)}


2. Running Main() from TestPlan
Few weeks back, I wanted to run the Main() function from Testplan. It is very old suite ( 10 years old). I thought, Silktest does not have any provision to call Main () function. I put the query into Borland forum and I got the answer.
Solution:
We have to represent the Main() as testcase. We should not change the hierarchy/indentation for script and testcase statements. See the sample plan below.



[-] SilkTest Issues
[ ] Developer: Palani Selvam
[ ] script: silkIssues.t
[ ] testcase: main()
[ ]



By this way, we can run the functions too..


[-] SilkTest Issues
[ ] Developer: Palani Selvam
[ ] script: silkIssues.t
[ ] // testcase: main()
[ ] testcase: MyTestCalls5 ()


Tuesday, July 22, 2008

VisualTest - Pressing Shortcut Key

Each GUI testing tool contains a way to press shortcut keys. Visual Test also has the feature to invoke shortcuts. It is similar to SendKeys in Windows Host Script. Below code I have written around eight years ago.

Visual Test code - To invoke Shortcut key



'---------------------
' Method : ShortcutKeys
' Author : T.Palani Selvam
' Purpose : Play shortcut keys.
' Parameters: sDatavalue, String - Contains a file name.
' Returns : Returns Integer data type(True or False.)
' Caller : SwitchSpecialTags
' Calls : - Nil
'----------------------
Function ShortcutKeys(sDataValue As String) As Integer
Dim iPosition As Integer
Dim sFirst As String
Dim sLast As String

ShortcutKeys = False

While (Instr(LCase(sDataValue),"+")<> 0 )
iPosition = Instr(LCase(sDataValue),"+")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 1)
sDataValue = sFirst + sLast
Wend


If (Instr(LCase(sDataValue),"ctrl")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"ctrl")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 4)
sDataValue = sFirst + "^" + sLast
End IF

If (Instr(LCase(sDataValue),"shift")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"shift")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 5)
sDataValue = sFirst + "+" + sLast
End IF

If (Instr(LCase(sDataValue),"alt")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"alt")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 3)
sDataValue = sFirst + "%" + sLast
End IF

If (Instr(LCase(sDataValue),"tab")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"tab")
sFirst = Left(sDataValue, iPosition - 1)
sLast = Mid$(sDataValue, iPosition + 3)
sDataValue = sFirst + "{TAB}" + sLast
End IF

If (Instr(UCase(sDataValue),"DELETE")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"DELETE")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 6)
sDataValue = sFirst + "{DEL}" + sLast
ElseIf (Instr(UCase(sDataValue),"DEL")<> 0 ) Then
iPosition = Instr(UCase(sDataValue),"DEL")
sFirst = Left(sDataValue, iPosition - 1)
sLast = Mid$(sDataValue, iPosition + 3)
sDataValue = sFirst + "{DEL}" + sLast
End IF


If (Instr(LCase(sDataValue),"enter")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"enter")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 5)
'sDataValue = sFirst + "{ENTER}" + sLast
sDataValue = sFirst + "~" + sLast
End IF

If (Instr(LCase(sDataValue),"right")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"right")
sFirst = Left(sDataValue, iPosition - 1)
sLast = Mid$(sDataValue, iPosition + 5)
sDataValue = sFirst + "{RIGHT}" + sLast
End IF

If (Instr(LCase(sDataValue),"left")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"Left")
sFirst = Left(sDataValue, iPosition - 1)
sLast = Mid$(sDataValue, iPosition + 4)
sDataValue = sFirst + "{LEFT}" + sLast
End IF

If (Instr(LCase(sDataValue),"down")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"down")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 4)
sDataValue = sFirst + "{DOWN}" + sLast
End IF

If (Instr(LCase(sDataValue),"up")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"up")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{UP}" + sLast
End IF

If (Instr(UCase(sDataValue),"ESCAPE")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"ESCAPE")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 6)
sDataValue = sFirst + "{ESC}" + sLast
ElseIf (Instr(UCase(sDataValue),"ESC")<> 0 ) Then
iPosition = Instr(UCase(sDataValue),"ESC")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 3)
sDataValue = sFirst + "{ESC}" + sLast
End IF

If (Instr(UCase(sDataValue),"INSERT")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"INSERT")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 6)
sDataValue = sFirst + "{INS}" + sLast
ElseIf (Instr(UCase(sDataValue),"INS")<> 0 ) Then
iPosition = Instr(UCase(sDataValue),"INS")
sFirst = Left(sDataValue, iPosition - 1)
sLast = Mid$(sDataValue, iPosition + 3)
sDataValue = sFirst + "{INS}" + sLast
End IF

If (Instr(UCase(sDataValue),"BREAK")<> 0 ) Then
iPosition = Instr(UCase(sDataValue),"BREAK")
sFirst = Left(sDataValue, iPosition - 1)
sLast = Mid$(sDataValue, iPosition + 5)
sDataValue = sFirst + "{BREAK}" + sLast
End IF

If (Instr(LCase(sDataValue),"f1")<> 0 ) Then
iPosition = Instr(LCase(sDataValue),"f1")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{F1}" + sLast
End IF

If (Instr(uCase(sDataValue),"F2")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F2")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{F2}" + sLast
End IF

If (Instr(uCase(sDataValue),"F3")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F3")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{F3}" + sLast
End IF

If (Instr(uCase(sDataValue),"F4")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F4")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{F4}" + sLast
End IF

If (Instr(uCase(sDataValue),"F5")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F5")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{F5}" + sLast
End IF

If (Instr(uCase(sDataValue),"F6")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F6")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{F6}" + sLast
End IF

If (Instr(uCase(sDataValue),"F7")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F7")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{F7}" + sLast
End IF

If (Instr(uCase(sDataValue),"F8")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F8")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{F8}" + sLast
End IF

If (Instr(uCase(sDataValue),"F9")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F9")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 2)
sDataValue = sFirst + "{F9}" + sLast
End IF

If (Instr(uCase(sDataValue),"F10")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F10")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 3)
sDataValue = sFirst + "{F10}" + sLast
End IF

If (Instr(uCase(sDataValue),"F11")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F11")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 3)
sDataValue = sFirst + "{F11}" + sLast
End IF

If (Instr(uCase(sDataValue),"F12")<> 0 ) Then
iPosition = Instr(uCase(sDataValue),"F12")
sFirst = Left(sDataValue, iPosition -1)
sLast = Mid$(sDataValue, iPosition + 3)
sDataValue = sFirst + "{F12}" + sLast
End IF

Logwrite ("Shortcut key processed: " + sDataValue, 1)

sDataValue = Trim(lCase(sDataValue)) 'Because some times, shortcut keys are not functioned in Upper case.

Play sDataValue

ShortcutKeys = True

End Function

Saturday, July 19, 2008

Excel Automation Using VBScript

Using VBScript, we can automate most of the Excel verification activities. In one project we can export reports to Excel. I have to verify the cell value, font color and Background color. It is difficult task to verify each cell property by any GUI testing tool. All tools are used to identify Excel Grid (Workbook) as Custom Object. I am using VBScript to read the excel contents. Another advantage, you can use the VBScript against different versions of Excel such as 2002, 2003 and 2007. But you need to change the code for Excel 2003 and 2007, if you have done by using GUI objects.

Below I put one Visual Basic script code. It reads the given excel file and put the details of each cell into a log file. Copy all contents from below textbox and save it as MyExcel.vbs and try to run this VBS file. You can run this script by using any GUI Testing tool. Command line call should be cscript MyExcel.vbs sExcelFile iStartRow iStartCol iEndRow iEndCol iSheetIndex

To Know more about this VBA Help, download help from this link Microsoft Office 2003 Editions: Excel VBA Language Reference

If you are unable to run any VBScript, See my earlier post Unable to run VBS or CScript in Windows XP .

VB Script to Read Excel Contents



' USAGE: MyExcel.vbs "D:\VB\Complex.xls" iStartRow iStartCol iEndRow iEndCol iSheetIndex
'cscript MyExcel.vbs "D:\VB\Complex.xls" 1 1 30 12 2

'******** Variables Declaration
' Files section
'XLS File name
gsFile="D:\VB\Complex.xls" 'File with macros
gsLogFile="D:\VB\Results_vbs.log"

Dim gsExcelFile, giStartRow, giStartCol, giEndRow, giEndCol, giSheetIndex
Dim gsResultsFile 'Text file name
gsDirSeparator = "\" 'Directory separator character


If WScript.Arguments.Count = 6 Then
gsExcelFile = WScript.Arguments.Item(0)
giStartRow = CInt (WScript.Arguments.Item(1))
giStartCol = CInt (WScript.Arguments.Item(2))
giEndRow = CInt (WScript.Arguments.Item (3))
giEndCol = CInt (WScript.Arguments.Item (4))
giSheetIndex = CInt (WScript.Arguments.Item (5))
'To Read the Excel file
'ReadExcel gsFile, 1, 1, 30, 12, 2
'WScript.Echo "ReadExcel " , gsExcelFile, giStartRow, giStartCol, giEndRow, giEndCol, giSheetIndex
ReadExcel gsExcelFile, giStartRow, giStartCol, giEndRow, giEndCol, giSheetIndex

Else
'WScript.Echo "Usage: MyExcel.vbs sExcelFile iStartRow iStartCol iEndRow iEndCol iSheetIndex"
'WScript.Quit
ReadExcel gsFile, 1, 1, 30, 12, 2
End If

'ReadExcel gsFile, 1, 1, 30, 12, 2

'---------------------------------
' Method : ReadExcel
' Author : T. Palani Selvam
' Purpose : Reading Excel contents.
' Parameters: - Nil
' Returns : - Nil
' Caller : - Nil
' Calls : - Nil

' Revision History:
'
' [No] da-mon-year Name: Action:
' [ 1] 07-Nov-2007 Palani Created first version
'---------------------------------
Sub ReadExcel(sExcelFile, iStartRow, iStartCol, iEndRow, iEndCol, iSheetIndex)

'WScript.Echo "ReadExcel " , sExcelFile, iStartRow, iStartCol, iEndRow, iEndCol, iSheetIndex
'ReadExcel(sExcelFile As Variant, iStartRow As Integer, iStartCol As Integer, iEndRow As Integer, iEndCol As Integer,iSheetIndex As Integer)

' Purpose: For Excel verification
' To Read the Excel and write into a file
' Each cell content
' Each cell - Foreground color, font name, font style, font size and Background color.


Dim sExcelPath 'As Variant 'Excel file

'********** Excel object declaration **********'
' Excel Application object
Dim objExcel 'As Excel.Application
Dim objXLWorkbooks 'As Excel.Workbooks
Dim objXLWorkbook 'As Excel.Workbook

Dim WorkSheetCount 'As Variant 'Work sheets count in a excel
Dim CurrentWorkSheet 'As Excel.Worksheet ' Current worksheet
Dim objCells 'As Excel.Range
Dim objCurrentCell 'As Variant
Dim objFont 'As Variant

' Result contents
Dim sCellValue 'As Variant
Dim sShowCellValue 'As Variant
Dim sFontName 'As Variant
Dim sFontStyle 'As Variant
Dim iFontSize 'As Variant
Dim iBackColorIndex 'As Variant
Dim iForeColorIndex 'As Variant
Dim iBackColorIndex2 'As Variant
Dim iForeColorIndex2 'As Variant
Dim sResult 'As Variant


' Row and Col integer variables
Dim iUsedRowsCount 'As Integer
Dim iUsedColsCount 'As Integer
Dim iTop, iLeft 'As Integer
Dim iRow 'As Integer 'Row item
Dim iCol 'As Integer 'Col item
Dim iCurRow 'As Integer
Dim iCurCol 'As Integer


If (sExcelFile = "") Then
sExcelPath = "D:\VB\Contacts.xls"
Else
sExcelPath = sExcelFile
End If

if (iSheetIndex = "") Then
iSheetIndex =1
End If


FileDeleteAndCreate (gsLogFile)

'XL file check
If (FileExists (sExcelPath) <> 0) Then
LogWrite ("The Excel file " & Chr(34) & sExcelPath & Chr(34) & " does not exit!")
'WScript.Echo "The Excel file, " & Chr(34) & sExcelPath & Chr(34) & " does not exit!"
'WScript.Quit
Else
LogWrite ("The XL file " & sExcelPath & " exists.")
End If

Set objExcel = CreateObject("Excel.Application")
objExcel.Workbooks.Open sExcelPath, False, True
'WScript.Echo "Reading data from " & sExcelPath
' objExcel.ExecuteExcel4Macro

'On Error GoTo ErrorHandler1
On Error Resume Next


WorkSheetCount = objExcel.Worksheets.Count
'WScript.Echo "We have " & WorkSheetCount & " worksheets."
'Set objXLWorkbook = objExcel.Workbooks(1)
Set objXLWorkbook = objExcel.ActiveWorkbook
'objXLWorkbook.RunAutoMacros

Set CurrentWorkSheet = objExcel.ActiveWorkbook.Worksheets(iSheetIndex) 'iSheetIndex worksheet
'Set CurrentWorkSheet = objExcel.ActiveWorkbook.Worksheets(1) 'First worksheet
' CurrentWorkSheet = objExcel.Worksheets(1) 'First worksheet


iUsedRowsCount = iEndRow 'CurrentWorkSheet.UsedRange.Rows.Count
iUsedColsCount = iEndCol 'CurrentWorkSheet.UsedRange.Columns.Count
iTop = iStartRow 'CurrentWorkSheet.UsedRange.Row
iLeft = iStartCol 'CurrentWorkSheet.UsedRange.Column

' Cells object
CurrentWorkSheet.Cells.Activate

For iRow = iTop To iUsedRowsCount '(iUsedRowsCount - 1)
'Read All rows
For iCol = iLeft To iUsedColsCount '(iUsedColsCount - 1)
'Read all Columns

sResult = ""

Set objCurrentCell = CurrentWorkSheet.Cells(iRow, iCol)
sCellValue = objCurrentCell.Value

'If ((sCellValue = empty) Or (sCellValue = "empty")) Then
If ((sCellValue = empty)) Then
sCellValue = "empty"
Else
Set objFont = objCurrentCell.Font
sFontName = objFont.Name

sFontStyle = objFont.FontStyle
iFontSize = objFont.Size
iForeColorIndex = objFont.Color
iForeColorIndex2 = objFont.ColorIndex

If (sFontName = Empty) Then
sFontName = "empty"
End If
If (sFontStyle = Empty) Then
sFontStyle = "empty"
End If
If (iFontSize = Empty) Then
iFontSize = "-99999999"
End If
If (iForeColorIndex = Empty) Then
iForeColorIndex = "99999999"
End If
If (iForeColorIndex2 = Empty) Then
iForeColorIndex2 = "99999999"
End If
sResult = "Reading Cell {" & CStr(iRow) & "," & CStr(iCol) & "}," & sCellValue & "," & sFontName & "," & CStr(sFontStyle) & "," & CStr(iFontSize) & "," & CStr(iForeColorIndex) & "," & CStr(iForeColorIndex2)

LogWrite (sResult)

End If
Set objCurrentCell = Nothing

Next

Next

' This will prevent Excel from prompting us to save the workbook.
objExcel.ActiveWorkbook.Saved = True
Set CurrentWorkSheet = Nothing

'objExcel.Worksbooks.Close
objExcel.Quit

''Set CurrentWorkSheet = Nothing
Set objExcel = Nothing


MsgBox "Read COmpleted.", vbOKOnly, "Exec Over"
Exit Sub

ErrorHandler1:
MsgBox "Error # " & CStr(Err.Number) & " " & Err.Description
Err.Clear ' Clear the error.

End Sub

'---------------------------------
' Method : Logwrite
' Author : T. Palani Selvam
' Purpose : Append the given message into Log file.
' Parameters: sMsg - String, Contains logging message.
' Returns : - Nil
' Caller : - Nil
' Calls : - Nil

' Revision History:
'
' [No] da-mon-year Name: Action:
' [ 1] 07-Nov-2007 Palani Created first version
'---------------------------------
Sub LogWrite(sMsg)
Const ForAppending = 8
'FileName = "D:\VBs\Mysamples\1create.txt"

Set objFSO = CreateObject("scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile (gsLogFile, ForAppending, True)

objTextFile.WriteLine date & " " & time & ": " & sMsg
objTextFile.Close

Set objTextFile = Nothing
Set objFSO = Nothing
End Sub

'---------------------------------
' Method : FileExists
' Author : T. Palani Selvam
' Purpose : Checks the given file is avialable or not.
' Parameters: - Nil
' Returns : - Returns As Boolean
' Caller : - Nil
' Calls : - Nil
'---------------------------------
Function FileExists(strPathName)
'return 0 if a file exists else -1
Dim ObjFSO

Set ObjFSO = CreateObject("Scripting.FileSystemObject")

if ObjFSO.FileExists(strPathName) = False then
FileExists = -1
else
FileExists = 0
end If

Set ObjFSO = Nothing
End Function

'---------------------------------
' Method : FileDeleteAndCreate
' Author : T. Palani Selvam
' Purpose : To delete the file if exists..
' Parameters: - Nil
' Returns : - Returns As Boolean
' Caller : - Nil
' Calls : - Nil
'---------------------------------
Function FileDeleteAndCreate(strFileName)
' delete
Set objFSO = CreateObject("Scripting.FileSystemObject")

On Error Resume Next
Set objTextFile = objFSO.GetFile(strFileName)
objTextFile.Delete

Set objTextFile = objFSO.CreateTextFile(strFileName)

objTextFile.Close
Set objTextFile = Nothing
Set objFSO = Nothing

End Function

'---------------------------------
' Method : Initialize
' Author : T. Palani Selvam
' Purpose : Initial actions & arrangements will be completed.
' Parameters: - Nil
' Returns : - Nil
' Caller : - Nil
' Calls : - Nil
'---------------------------------
Sub Initialize()
'CHECKING INPUT FILES ARE AVAILABLE OR NOT
gsLogFile = App.Path & "\Results.log"
End Sub

Wednesday, July 16, 2008

Winrunner - Version History

I was going through Wilsonmar site few months back. He has listed winrunner product version history. Already you know that Winrunner product line will be ended soon. Source: Wilsonmar Page

Winrunner - Product Version History


  • Version 8.2 became available Aug 15, 2005.

  • Version 8.0 became available Jan 2005

  • Version 7.6 is a point release available Jan 2004.

  • Version 7.5 was a major release out March 2002.

  • Version 7.01 is the release sent to maintenance licensees on August 2001.

  • Version 6.02 is needed for Windows 2000.

  • Version 6.0 SP1 (2.23 MB Web.z and info.ini files) created 11/29/99.

Tuesday, July 15, 2008

Silktest - File Download window

Sometimes Silktest is not identifying FileDownload objects properly. To save it, we need to use TypeKeys. I used following code snippet to save a file from Browser.

Sample 4Test code



[+] Boolean SaveFile (String sFile)
[ ] Boolean bResult = FALSE
[+] do
[+] if (FileDownload.Exists(1))
[ ] Print ("FileDownload exists.")
[ ] FileDownload.SetActive ()
[ ] Sleep (1)
[ ] FileDownload.Save.Click (1,10,3)
[ ] Sleep (3)
[ ]
[ ] Window wActive = Desktop.GetActive ()
[ ] Print ("Window: {wActive}")
[ ] // DialogBox("File Download").DialogBox("Save As")
[ ] wActive.TypeKeys (sFile)
[ ] wActive.TypeKeys ("", 1)
[ ] wActive.TypeKeys ("", 1)
[ ] wActive.TypeKeys ("S",1)
[ ]
[ ] bResult = TRUE

[+] else
[ ] Print ("BrowserFileDownload does not exist.")
[+] except
[ ] ExceptLog ()
[ ]
[ ] return bResult
[ ]

Saturday, July 12, 2008

Winrunner - Expert Questions

Earlier I had prepared set of questions to ask for WinRunner interview. I have given few of them below:

Expert Questions - WinRunner


  1. Scope of public, static, extern, auto variables.

  2. Differnce between Compiled Module and Main script

  3. What's the purpose of the wrun.ini file?

  4. What is the difference between "set_window" and "win_activate"?

  5. What is a checkpoint and what are different types of checkpoints?

  6. What are the virtual objects and how do you learn them?

  7. How can you merge GUI maps & tell me the possible ways?

  8. What is meant by GUI mapping? What is the concept behind that?

  9. What are the difference between calling a script and compiled module?

  10. What is the difference between loading a script and calling a script?

  11. Why do we go for eval to call a script?

  12. What is the difference between treturn, texit, return?

  13. What is the usage of tl_step?

  14. Tell about Match statement in WinRunner?

  15. What is function generator? How to use this in Winrunner?

  16. What is the difference between GUI_close_all and GUI_unload_all() ?

  17. Tell me about substr, index, split?

  18. What is synchronization point and tell me the usage of that?

  19. What is the difference between writing a function and writing a script?

  20. How do you handle unexpected events and errors?

Tuesday, July 8, 2008

Comparison of SilkTest and Winrunner

Last month, I have posted Comparison of SilkTest and QuickTest Professional . Then I thought to put one more comparison with Winrunner. This time I have compared in low level. It means comparing functions and file structure level. Hope it will be useful for automation newbies.

Wiki pages
Silktest on Wiki
Winrunner on Wiki

Code samples for both tools
Sample 4test code snippets for SilkTest
Sample TSL code snippets for Winrunner

References:


  1. SILKTEST AND WINRUNNER FEATURE DESCRIPTIONS - By Horwath/Green/Lawler

  2. Comparison of SilkTest and QuickTest Professional



Comparison Table: SilkTest Vs Winrunner

Features

SilkTest

WinRunner

Project fileSilktest has two types of extensions to represent projects. One is vtp file, which is usual one. Another one is stp file, which is zipped version of silktest project. <ProjectName>.ini or partner.ini has silktest settings.No project file.
Tool Configuration<ProjectName>.ini or partner.ini has silktest settings for particular project. Silktest has options set (*.opt) to configure the project level settings.Initial startup configurations are stored in wrun.ini file.
Test Environment vaiablesSetOption and GetOption methods are used to set various silktest settings. GetTestCaseName, GetTestCaseErrorCount, GetTestCaseState and GetTestCaseWarningCount functions are used to get information about testcases.setvar and getvar functions available to set or get test variables. Few options are : cs_run_delay, cs_fail, delay_msec, rec_item_name, rec_owner_drawn, searchpath, silent_mode, single_prop_check_fail, synchronization_timeout, tempdir and speed
Script RecorderOnly one mode for different activities.Record Testcase, Application State, Actions.Two modes. 1. Context sensitive mode 2. Analog mode.
Code ViewClassic 4Test, Visual 4TestOnly one view
Test ScriptScript is a single file. Extension is *.t. One script can contain many testcases.Actually Script is a folder and have set of supporting files.There will a file 'script'. That contains actual script.
  1. a db folder for asc data
  2. an exp folder for expected results.
  3. a debug folder for using during debug runs.
TestsTermed as Testcase. Each Testcase has block of coding statements.No separate terms.
Objects RepositoryOfficial term is frame file. They can be edited directly from the Editor. File extension is (*.inc). Objects are called as Window declarations. User can declare variables and functions inside frame file.Termed as GUI Map. Maintained as separate file. With the help of utility, objects can be modified. Two types as per Winrunner setting. They are 'GuiMap file per Test' and 'Global GUI Map'. File extension is same for both types as (*.gui). User can not declare variables and functions inside GUI Map file.
Physical descBased on Caption, Prior text, Index, Window ID, Location and Attribute.Wildcards can be used.Wildcards can be used.Identifying based on obligatory properties. An optional property is used only if the obligatory properties do not provideunique identification of an object. In cases where the obligatory and optional properties do not uniquely identify an object, WinRunner uses a selector. For example, if there are twoOK buttons with the same MSW_id in a single window, WinRunner would use a selector to differentiate between them. Two types of selectors are available:
  1. A location selector uses the spatial position of objects.
  2. An index selector uses a unique number to identify the object in a window.
Logical name - used to identify the objectCalled as Test Identifier. It is similar to variable. It should not have space or any other special characters. It is not similar to variable. It can have space and few special characters.
Object Representation
Based on true object hierarchy. Dynamic representation sample is given below:
Syntax: class("tag").class("tag").class("tag")
Example: MainWin("Text Editor - *").DialogBox("Find").TextField("Find What")
Based on Flat list. There will be only two levels. Top level will be window and leaf level will be child objects. Dynamic representation sample
Syntax: "{class: <class>, MSW_class: <WR class>,<property>:<propertyvalue>}"
Example: set_window("{class: window, MSW_class: html_frame,active:1}",20);
Function library Termed as Include (*.inc) file. Compile modules. Again it is similar to Test Script. Test Library/API calls use "frame.inc". You have to use in the beginning of script. Termed as Compiled module. GUI_load and GUI_open functions are used to load GUI Maps. You can call above functions anywhere from the script. You can call comipiled modules like below:
  1. reload( "C:\\MyAppFolder\\" & "flt_lib" );
  2. load( "C:\\MyAppFolder\\" & "flt_lib" );
CheckPoint Provided Verify and Verify Properties functions. Provided various check points for different purposes.
Results Reporting Results are stored into *.res binary files. It can be converted into differnt formats. Multiple versions can be stored into single file.Winrunner results are stored in separate folder for each run. Result folder contain two files:
  1. _t_rep.hdr -> Header file, which contains test run info
  2. _t_rep.eve -> results file, which contains info about each execution.
Library Browser Library Browser Function Generator
User Message Print(), Printf() functions report_msg() function.
Result Function Verify (), raise () and Reraise () functions tl_step () function
Exception Handling <do-except> block is available and few supporting functions. Winrunner does not have explicitly similar to do-except or try-catch block. But it has different wizards to handle different type of exceptions such as Pop-up exceptions, TSL exceptions, Object exceptions and Web exceptions.
Test/Error Recovery Powerful Default recovery system is set based on extension and MainWindow. It can be extended by using BaseState. Recovery Scenarios, which is available from Winrunner 7.5. Lower versions do not have this feature.
Wait statements Sleep (10) ' 10 seconds to wait Wait (10) ' 10 seconds to wait
Halt Execution temporarily Agent.DisplayMessage () - temporarily stopping execution with a message.pause() - pauses test execution and displays a message
To activate a windowMyWin.SetActive () set_window ("Shell_TrayWnd", 2);
Accessing DLLsOnly Standard DLLs. It does not support the COM/ActiveX DLLs, which are created by VB/.NET Both COM and Standard DLLs are supported. COM DLL support is available from Winrunner 7.5
Database Verification Having built-in functions to extract information from Databases through ODBC32 Interface (DSNs)Having built-in functions to extract information from Databases through ODBC32 Interface (DSNs). WinRunner also provides a visual recorder to create a Database Checkpoint used to validate the selected contents of an ODBC compliant database within a testcase.
Data functions Good Good. Having extensive support for SpreadSheet (Excel).
Scripting Language 4Test scripting language. It is a object oriented scripting language. Similar to C++ TSL - Test Script Language. It is based on the C programming language.
Data types Set of data types like integer, string and number are available. User can create their own data types also.No data types
Mostly using - Compound Data type LIST data type. ARRAY. Subscript can be integer or string.

Monday, July 7, 2008

Winrunner -Scope of Variables

Winrunner has four different types of variables. They are used inside the funciton, outside the function and calling from different tests.

auto : An auto variable can only be declared within a function and is local to that function.
It exists only while the function is running. A new copy of the variable is created each time the function is called.

static : A static variable is local to the function, test, or compiled module in which it is declared. The variable retains its value until the test is terminated by a Stop command.

public : A public variable can only be declared within a test or module, and is available for all functions, tests, and compiled modules.

extern : An extern declaration indicates a reference to a public variable declared outside of the current test or module.

For more info, See the Winrunner Help.

Friday, July 4, 2008

Winrunner - Tooltip verification

Winrunner does not have any built-in function, to get tooltip. Jerry McGowan has written TSL code to verify the tooltip. I was searching my old winrunner scripts. At that time, I found this sample code.

Already I have written a post for tooltip verification by QTP. Post QTP - Tooltip verification in Browser

Winrunner (TSL) code - To verify Tooltip

############################################################ # Function: # check_tootip() # # Description: # Moves the mouse to a specified location within an object # to activate the object popup text message. The expected # popup message is then compared to the actual text, and # the function returns E_OK if the text is found. # # Parameters: # object - Name of the object # tip - The expected tip text that should popup when # the mouse is moved over the object. # x - The x position within the object to move the mouse # y - The y position within the object to move the mouse # # Returns: # "E_OK" if the tip is found, "E_NOT_FOUND" otherwise. # # Syntax: # rc = check_tooltip(object,tip,x,y); # # Example: # check_tooltip("ToolbarWindow32","Create Order",5,5); # ############################################################ function check_tooltip(in object, in tip, in x, in y) { auto parent, text; # Move to the first button of the toolbar obj_mouse_move (object, x,y); # Wait until the tip is displayed. wait(1); # Get the text for the window. obj_get_info(object,"parent",parent); win_get_text(parent, text); # You can then search the contents of text to see if # the expected tip is displayed. if (index (text, tip) > 0) { tl_step ("Tool tip", PASS, tip); return (E_OK); } else { tl_step ("Tool tip", FAIL, tip); return (E_NOT_FOUND); } }; ############################################################ # End of script ############################################################

Thursday, July 3, 2008

Winrunner - SET_WINDOW and WIN_ACTIVATE

This is one of my favorite and Expert questions in Winrunner.

  1. What is the difference between "set_window" and "win_activate"?
  2. When would you use "set_window" and when would you use "win_activate"?

win_activate has the syntax win_activate(window);. The win_activate function
makes the specified window the active window by bringing it into focus and
raising it to the top of the display. (It is the equivalent to clicking on the
window banner)

Set_window has the following syntax: set_window(window,[time]);
The set_window function directs input to the right application window. This
directs the GUI map to this window. It also sets the scope for object
identification in the GUI map.

The most important difference is that set_window has a timing option.
WinRunner will wait a maximum of the number used in the function, PLUS the system set timeout, to wait for the window to appear. Win_activate assumes the window is already on the desktop and has no timing option.

Tuesday, July 1, 2008

QTP - Smart Identification

Sometimes back, I was in a QTP interview panel. Most of the candidates do not know about smart identification. That's why, I thought to write to this post.

Need of Smart Identification
Smart identification is a technique in QuickTest Professional. It is used to identify the objects, even though few mandatory properties are changed at run time.

Smart Identification Overview
The Smart Identification dialog box enables you to create and modify the Smart Identification definition that QuickTest Professional uses for a selected test object class. When the recorded definition for an object does not enable QTP to identify an option, QuickTest Professional uses the smart identification definition (if defined and enabled) to identify the object.

Smart Identification uses two types of properties:


  1. Base filter properties: The most fundamental properties of a particular test object class; those whose values cannot be changed without changing the essence of the original object. For example, if a Web link's tag was changed from <A> to any other value, you could no longer call it the same object.

  2. Optional filter properties: Other properties that can help identify objects of a particular class as they are unlikely to change on a regular basis, but which can be ignored if they are no longer applicable.


To know more about Smart Identification, You can see the QuickTest Professional Help for following topics:

  1. About Configuring Smart Identification

  2. Understanding the Smart Identification Process

  3. Reviewing Smart Identification Information in the Test Results

  4. Walking Through a Smart Identification Example

  5. Step-by-Step Instructions for Configuring a Smart Identification Definition