Record /Playback Myth

The test automation tool vendors market their product as the main feature of the tool is the ability to capture the user actions and later to playback them. Here is the basic paradigm for GUI-based automated regression testing – the so called Record/Playback method (also called as Capture/Replay approach)

1. Design a test case in the test management tool.

2. Using the capture feature of the automation testing tool record the user actions. The result is a macro-like script where each user action is presented.

3. Enhance the recorded script with verification points, where some property or data is verified against an existing baseline. Add delay and wait states points where the different actions are synchronized.

4. Playback the scripts and observe the results in the log of the test management tool.

The basic drawback in this method is the scripts resulting from this method contain hard-coded values which must change if anything at all changes in our AUT. The costs associated with maintaining such scripts are astronomical, and unacceptable. These scripts are not reliable, even if the application has not changed, and often fail on replay (pop-up windows, messages, and other things can happen that did not happen when the test was recorded).
If the tester makes an error entering data, etc., the test must be re-recorded. If the application changes the test must be re-recorded. All that is being tested are things that already work. Areas that have errors are encountered in the recording process (which is manual testing, after all). These bugs are reported, but a script cannot be recorded until the software is corrected. So logically nothing is tested by this approach.


So, avoid using "Record/Playback" as a method of automating testing. This method is fraught with problems, and is the most costly (time consuming) of all methods over the long term. The record/playback feature of the test tool is useful for determining how the tool is trying to process or interact with the application under test, and can give us some ideas about how to develop your test scripts, but beyond that, its usefulness ends quickly.

Types of Test Automation Frameworks

There are several test automation frameworks available, among these the selection is made based on the factors such as reusability of both the scripts and the test assets. The different test automation frameworks available are as follows,
 Test Script Modularity
 Test Library Architecture
 Data-Driven Testing
 Keyword-Driven or Table-Driven Testing
 Hybrid Test Automation

Difference between Function and Sub

In VBScript, there are two types of procedures:

Sub Procedures
Function Procedures
Sub Procedures

A sub procedure is a series of VBScript statements, enclosed by Sub and End Sub statements which perform actions but do not return a value. A sub procedure can take arguments. If a sub procedure doesn’t receive any arguments, its Sub statement must include an empty parenthesis().

The following Sub procedure uses two intrinsic, or built-in, VBScript functions, MsgBox and InputBox , to prompt a user for information. It then displays the results of a calculation based on that information. The calculation is performed in a Function procedure created using VBScript. The Function procedure is shown after the following discussion.

Sub ConvertTemp()

temp = InputBox("Please enter the temperature in degrees F.", 1)

MsgBox "The temperature is " & Celsius(temp) & " degrees C."
End Sub

Function Procedures

A function procedure is a series of VBScript statements enclosed by the Function and End Function statements. A function procedure is similar to a sub procedure but it can return value to the calling function. A function procedure can take arguments (constants, variables or expressions that are passed to it by a calling procedure). If a function procedure has no arguments, it Function statement must include an empty set of parenthesis. A function returns a value by assigning a value to its name in one or more statements of the procedure. Since VBScript has only one base data type, a function always returns a variant.

In the following example, the Celsius function calculates degrees Celsius from degrees Fahrenheit. When the function is called from the ConvertTemp Sub procedure, a variable containing the argument value is passed to the function. The result of the calculation is returned to the calling procedure and displayed in a message box.

Sub ConvertTemp()
temp = InputBox("Please enter the temperature in degrees F.", 1)
MsgBox "The temperature is " & Celsius(temp) & " degrees C."
End Sub

Function Celsius(fDegrees)
Celsius = (fDegrees - 32) * 5 / 9
End Function
Tips:
To get data out of a procedure, you must use a Function. Remember, a Function procedure can return a value; a Sub procedure can't.
A Function in your code must always be used on the right side of a variable assignment or in an expression.
To call a Sub procedure from another procedure, type the name of the procedure along with values for any required arguments, each separated by a comma. The Call statement is not required, but if you do use it, you must enclose any arguments in parentheses.
The following example shows two calls to the MyProc procedure. One uses the Call statement in the code; the other doesn't. Both do exactly the same thing.
Call MyProc(firstarg, secondarg)

MyProc firstarg, secondarg

Notice that the parentheses are omitted in the call when the Call statement isn't used.

Data driven testing using excel in QTP

This is script for data driven using excel sheet.
In this script we are not importing excel sheet to datatable. Directly values are supplied to application from excel sheet.

set ex= CreateObject("Excel.Application")
Set a=ex.Workbooks.open("D:\excel.xls")
Set b=a.worksheets("Sheet1")

dim login, pwd

for i=1 to 3

login=b.Cells(i,"A").value
pwd=b.Cells(i,"B").value
msgbox login
msgbox pwd

next

"D:\excel.xls" is path of excel sheet.
"sheet1" indicates sheet name in which values are present.
A,B are column names in excel sheet.

we have excel sheet with values as shown below in d drive.
A B
1 2
3 4
5 6

Count & Close all browsers

QTP Script to get total count, names of all open browsers and to close them using descriptive programming..


Set ab=Description.Create
ab("micclass").value="Browser"
Set obj=Desktop.ChildObjects(ab)
msgbox obj.count
For i=0 to obj.count-1
c=obj(i).getroproperty("name")
msgbox(c)
obj(i).Close
Next

Descriptive programming example

This is an example for descriptive programming in QTP for a checkbox.
In this script we will check whether yahoologinpage(www.yahoomail.com) checkbox is checked or not

Set g=Browser("name:=Yahoo.*").Page("title:=Yahoo.*")
Set obj=Description.Create
obj("htmltag").value="Input"
obj("ClassName").value="webcheckbox"
obj("type").value="checkbox"
Set a=g.childobjects(obj)
c=a(0).getroproperty("checked")
msgbox(c)
If c=0 Then
msgbox "checkbox is not checked"
else
msgbox"checkbox is checked"
End If

Data Driven Testing using Notepad in QTP

Set
f=createobject("scripting.filesystemobject")
Set f1=f.createtextfile("d://file1.txt")
f1.writeline"aaa bbb"
f1.writeline"ccc ddd"
f1.writeline"eee fff"
f1.writeline"ggg hhh"
f1.writeline"iii jjj"

The above script creates a notepad in "d" drive with name file1

aaa bbb
ccc ddd
eee fff
ggg hhh
iii jjj

values are stored in file1.txt.

Set f2=f.opentextfile("d://file1.txt")

While f2.atendofstream<>true
f3=f2.readline
x=split(f3," ")
msgbox x(0)
msgbox x(1)

Wend

The above script is used for data driven using notepad directly.here we are not importing data to excel sheet.

directly values are retreived from notepad.

we are using while loop and reading each line till the end.

split function splits the line where space(" ")occurs.

line is divided to 2 parts.one before space and other after space

for example we have 1st line in notepad as aaa bbb

here aaa is 1st part and bbb is 2nd part

x(0)=aaa

x(1)=bbb

all values are read this way using while loop.
One point to note here is if any line is empty in notepad datadriven testing is stopped before that line.

It will not proceed further.so we have to give values without any empty lines in notepad.

To make u more clear,
suppose u have

aaa bbb

ccc ddd

Datadriven is stopped at aaa and bbb only because next line is empty.datadriven is stopped after 1st line.

Some common QTP functions

In this article I captured some functions which are captured from various sources.

How to check for the broken links (both textlinks and image links) on the page with VB script and not the checkpoints.
---------------------------------------------------------
set
obj=Browser("name:=Blackboard.*").Page("title:=Blackboard.*").Frame("name:=main.*").object.all.tags("IMG")

msgbox obj.length

For each element in obj
s1=element.nameProp

If Browser().Page().Frame().Image("file
name:="&s1,"index:=0").exist(0) then
If Browser().Page().Frame().Image("file
name:="&s1,"index:=0").Object.complete="True" then

msgbox "pass"

else
msgbox "fail"

end if
end if

Next
---------------------------------------------------------


Multiple Exit ways

It’s very easy to control the entry gate to an action or function - there’s only one way to enter them. However, the number of exit gates can vary widely from 1 to many according to the inner logic of the action/function. Today I’m going to address managing multiple exit gates in actions and functions.
When everything goes according to plan, an action flow tends to be very simple. There may be inner loops, If or Select switches, but for the most part, the flow just runs straight down to the last line. The problems usually appear when… well, problems appear. If an application error occurs, or even just an unexpected business logic behavior, there might be no escape from immediately exiting the action. There’s no point trying to input 20 data fields, if the form they’re in didn’t even open, is there?The function is something like the following:

‘.Action Code

If CritialCondition = False Then ExitAction

‘.Continue Action


But this is uninformative. So we add a reporter command:


If CritialCondition = False Then

Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"
ExitAction
End If
And we probably got some objects to remove from memory:
If CritialCondition = False Then

Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"

oFile.Close

Set oFile = Nothing

ExitAction

End If
============================================

Ho wait, we’ve gathered some data we need to report back:
If CritialCondition = False Then

Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"

oFile.Close

Set oFile = Nothing

DataTable("out_EntityID", dtlocalsheet) = sEntityID

‘More here

ExitAction

End If


========================

Well, you probably get the picture. Pretty soon we get massive amounts of code in all the exit gates. This means we have duplicate code to maintain. Duplicate code is the digital manifestation of pure evil – and it’s never a good idea to have pure evil in you actions. Seriously though, this is exactly the kind of things that produces untraceable bugs, and it must be avoided at all cost.
So, how can we deal with this situation? One way is to create an exit gate function. It’s the ONLY function I ever put within an action, and not in an external file. Here’s an example of my action template, with the function:
Dim sResult ‘I store result data and values to be reported up the

‘action-call chain

Dim sActionReport ‘Instead of flooding the log with inner-action messages,

‘I store them, and report all of them at the exit gate.

‘Errors are still reported on-the-fly


‘Action code goes here


‘All the exit gates execute only one command : ActionEnd.

‘It receives two parameters: Boolean for Pass/Fail,

’string for the exit reason

If CriticalCondition = False Then Call ActionEnd(False, "Reason for exiting")


‘Rest of action


‘Even the normal successful action exit is managed through ActionEnd,

’so the last line in every action is:


Call ActionEnd(True, "Action successful")


Sub ActionEnd(bStatus, sReason)

‘Report details

Reporter.ReportEvent MicGeneral, "Inner Action Logs", sActionReport


If bStatus = True Then

Reporter.ReportEvent MicFail, "An error has occurred", sReason

Else

Reporter.ReportEvent MicPass, "Action successful", "See inner logs"

End if


‘Plant datatable info for action-call chain

DataTable("out_Status", dtlocalsheet) = bStatus

DataTable("out_Result", dtlocalsheet) = sResult

‘More if needed


‘Close objects and set to nothing here


‘Other needed exit code


ExitActionIteration

End Sub


With this mechanism, maintaining the exit code becomes very simple, and the logs are much more readable. Ok, so this solves the problem for actions, but what about functions? Well, obviously we can write an inner function within a function, but there is an alternative solution. It’s less elegant than the ActionEnd solution by far, and is harder to maintain, so I recommend using it only in a small number of very complex functions.
The solution is based on the Execute command, so I recommend reading about it in QTP’s help file in case you’re not familiar with it. In a nutshell, the Execute command takes a string, and runs its contents as if it were VBScript code. So for instance the command Execute "msgbox(2)" will pop a message box with the number 2. Here’s an example for the solution, applied to the ComplexFunc function:
Function ComplexFunc

Dim sExitCode

Dim sResult

Dim oFile ‘will be FSO textstream


’separate code lines by vbcrlf or ":"

sExitCode = "oFile.Close" & vbcrlf & _

"Set oFile = Nothing" & vbcrlf & _

"ComplexFunc = sResult"

‘More exit code


‘Function code goes here


‘Exit Gate

If CriticalCondition = False then

sResult = "False, No Connection"

Execute sExitCode

Exit Function

End if


‘More function code


‘Successful exit

Execute sExitCode

End Function



Creating and Calling user define funtion

Test Conditons: Creating and Calling user define funtion

1. Crate small add function and make it compile module.

2. calling that function in other test (using user defined data values)

[ Pre Requesties : Nothing ]

1a. open win runner blank test and add this below data

public function add(in a, in b)
{
return a+b;
}

1b. Go to File menu --> Test Properties (Test Properties window will open)
in General Tab --> Test Type= Compile module and ok

1c.Save the test in some location (Ex c:/tt )

2a.Before writing code , you have to load the funtction in to your folder , globally available to all tests.


2b. Go to Tools menu --> General Options
--- Select Folder option in the left pan.
-- Search Path for called test below enter the path of compile module
(c:/tt) and press "+" button to add in to.

2c. Write down the bleow code in the new test

load("c:/tt");
l= create_input_dialog("Enter First value");
j=create_input_dialog("Enter Second Value");
k=add(l,j);
report_msg(k);
unload("c:/tt");

WinRunner End-of-support and Migration Webinar

Make sure your HP emails always go straight to your inbox. Add sw-bulletins@info.hp.com to your address book! Need Help?
WinRunner End-of-Support Announcement
HP WinRunner Migration Webinar: A Case Study from Travelocity» Register NowLive date: Tuesday, March 11, 2008 Start time: 7:00 AM PT9:00 AM CT10:00 AM ET3:00 PM GMTSpeakers: Rachel Pilgrim, QA Manager,TravelocitySatish Atluri, HP QM Global Practices Roi Carmel, Functional Testing Product Manager, HP Software

Learn more

» WinRunner End-of-Support Announcement» WinRunner migration data sheet
Find out how to accelerate migration from WinRunner to QuickTest Professional »

IMPORTANT ANNOUNCEMENT FOR WINRUNNER USERSHP Software is announcing end-of-support for HP WinRunner software, all versions (7.5, 7.6, 8.0, 8.2, 9.2). This end-of-support is based on our decision to consolidate and focus our functional testing offerings (HP WinRunner and HP QuickTest Professional) to maximize value to our customers. For migration options, support end dates and a list of FAQs, read the entire announcement here.Migration WebinarTo assist you with the migration from HP WinRunner to HP QuickTest Professional, we are hosting a Webinar with HP Professional Services (PS) and Travelocity who pioneered the HP WinRunner to HP QuickTest Professional migration effort. In this Webinar, Travelocity will share how they leveraged Gallop Technologies’ WinQuick – an HP R&D validated and approved automated migration solution – to automatically migrate and re-architect their HP WinRunner code base to HP QuickTest Professional. You will learn:
• What options Travelocity evaluated before undertaking this migration
• How Travelocity was able to perform this migration within budget and in less time than expected while at the same time increasing adoption of HP QuickTest Professional across the enterprise
• How you can replicate Travelocity’s success in your own organization
Don’t miss this opportunity to get insights from a customer who had great success with this migration.

Technology for better business outcomes
» HP Software
» Sales
» Privacy Policy
» Unsubscribe

If you received this e-mail from a friend and/or would like to subscribe to our e-mail list to receive future promotions and special offers, please click here.HP respects your privacy. If you'd like to discontinue receiving e-mails from HP regarding special offers and information, please click here.For more information regarding HP's privacy policy or to obtain contact information please visit our privacy statement or write to us at: Privacy Mailbox, 20555 SH 249, Houston, Texas 77070, ATTN: HP Privacy MailboxHewlett-Packard websiteSign-up for Driver and Support Alerts

Verify Broken Links using VBscript (without checkpoints)

One of my friends just wanted to check for the broken links (both textlinks and image links) on the page with VB script and not the checkpoints.
So the answer for that was the following code
---------------------------------------------------------
set
obj=Browser("name:=Blackboard.*").Page("title:=Blackboard.*").Frame("name:=main.*").object.all.tags("IMG")

msgbox obj.length

For each element in obj
s1=element.nameProp

If Browser().Page().Frame().Image("file
name:="&s1,"index:=0").exist(0) then
If Browser().Page().Frame().Image("file
name:="&s1,"index:=0").Object.complete="True" then

msgbox "pass"

else
msgbox "fail"

end if
end if

Next
---------------------------------------------------------

Code provided by my friend Shiva

Multiple Exit ways

It’s very easy to control the entry gate to an action or function - there’s only one way to enter them. However, the number of exit gates can vary widely from 1 to many according to the inner logic of the action/function. Today I’m going to address managing multiple exit gates in actions and functions.
When everything goes according to plan, an action flow tends to be very simple. There may be inner loops, If or Select switches, but for the most part, the flow just runs straight down to the last line. The problems usually appear when… well, problems appear. If an application error occurs, or even just an unexpected business logic behavior, there might be no escape from immediately exiting the action. There’s no point trying to input 20 data fields, if the form they’re in didn’t even open, is there?
Thankfully, the nice guys and gals at Mercury have taken this into account, and have provided us with the ExitAction and ExitActionIteration commands. So usually we’ve got something like the following:

‘.Action Code

If CritialCondition = False Then ExitAction

‘.Continue Action

But this is uninformative. So we add a reporter command:

If CritialCondition = False Then

Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"
ExitAction
End If
And we probably got some objects to remove from memory:

If CritialCondition = False Then

Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"

oFile.Close

Set oFile = Nothing

ExitAction

End If
============================================

Ho wait, we’ve gathered some data we need to report back:

If CritialCondition = False Then

Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"

oFile.Close

Set oFile = Nothing

DataTable("out_EntityID", dtlocalsheet) = sEntityID

‘More here

ExitAction

End If

========================
Well, you probably get the picture. Pretty soon we get massive amounts of code in all the exit gates. This means we have duplicate code to maintain. Duplicate code is the digital manifestation of pure evil – and it’s never a good idea to have pure evil in you actions. Seriously though, this is exactly the kind of things that produces untraceable bugs, and it must be avoided at all cost.
So, how can we deal with this situation? One way is to create an exit gate function. It’s the ONLY function I ever put within an action, and not in an external file. Here’s an example of my action template, with the function:

Dim sResult ‘I store result data and values to be reported up the

‘action-call chain

Dim sActionReport ‘Instead of flooding the log with inner-action messages,

‘I store them, and report all of them at the exit gate.

‘Errors are still reported on-the-fly

‘Action code goes here

‘All the exit gates execute only one command : ActionEnd.

‘It receives two parameters: Boolean for Pass/Fail,

’string for the exit reason

If CriticalCondition = False Then Call ActionEnd(False, "Reason for exiting")

‘Rest of action

‘Even the normal successful action exit is managed through ActionEnd,

’so the last line in every action is:

Call ActionEnd(True, "Action successful")

Sub ActionEnd(bStatus, sReason)

‘Report details

Reporter.ReportEvent MicGeneral, "Inner Action Logs", sActionReport

If bStatus = True Then

Reporter.ReportEvent MicFail, "An error has occurred", sReason

Else

Reporter.ReportEvent MicPass, "Action successful", "See inner logs"

End if

‘Plant datatable info for action-call chain

DataTable("out_Status", dtlocalsheet) = bStatus

DataTable("out_Result", dtlocalsheet) = sResult

‘More if needed

‘Close objects and set to nothing here

‘Other needed exit code

ExitActionIteration

End Sub

With this mechanism, maintaining the exit code becomes very simple, and the logs are much more readable. Ok, so this solves the problem for actions, but what about functions? Well, obviously we can write an inner function within a function, but there is an alternative solution. It’s less elegant than the ActionEnd solution by far, and is harder to maintain, so I recommend using it only in a small number of very complex functions.
The solution is based on the Execute command, so I recommend reading about it in QTP’s help file in case you’re not familiar with it. In a nutshell, the Execute command takes a string, and runs its contents as if it were VBScript code. So for instance the command Execute "msgbox(2)" will pop a message box with the number 2. Here’s an example for the solution, applied to the ComplexFunc function:

Function ComplexFunc

Dim sExitCode

Dim sResult

Dim oFile ‘will be FSO textstream

’separate code lines by vbcrlf or ":"

sExitCode = "oFile.Close" & vbcrlf & _

"Set oFile = Nothing" & vbcrlf & _

"ComplexFunc = sResult"

‘More exit code

‘Function code goes here

‘Exit Gate

If CriticalCondition = False then

sResult = "False, No Connection"

Execute sExitCode

Exit Function

End if

‘More function code

‘Successful exit

Execute sExitCode

End Function