Você está na página 1de 13

Introduction to Parameterization with

QTP’s Local DataTable


November 23, 2009 · 44 comments

Parameterization is a process in which parameters, or variables are substituted for hard-


coded values which help perform the same operations on the AUT with multiple sets of
data. In other words, in QTP, parameterization helps automation developers test an
application with different data from a single action (or multiple actions) through multiple
iterations. Because the data changes each iteration, it must be stored in a data-pool, or in
multiple variables. This data-pool can be QTP’s DataTable, an Excel Spreadsheet
(external to QTP), Access DB, SQL Server, or any database of your choice. It can also
come from several Environment variables. This topic will describe parameterization with
QTP’s DataTable.

The trick to successful parameterization is cycling around a process. For example,


consider a flight booking/checkout process. You would first login to the application, find
and select the flight of your choice, make the purchase, and in the end view the
confirmation.

If you were to parameterize the above process, instead of ending your script at the
confirmation page, you would end it at the Find Flight page. This is because, when the
next iteration executes, it is already at the correct page which can enable the script to start
all over again at the expected point. In other words, our process should look like below:

Parameterization with DataTable


Before we start with the actual parameterization, we must first understand how data will
be retrieved from the DataTable and the settings that we need to make in order to cover
all the rows. In our example, we will test a few UserName and Passwords in the
HP/Mercury’s Demo AUT.

Below, I have created 2 columns in the Local (Action1) DataTable- UserName &
Password. You can create columns by simply double-clicking the Column heading:
Create Columns in DataTable

Next, I will create 4 rows with different sets of data:

Add Data to Columns

Below is the syntax to retrieve data from the DataTable’s local sheet:

'If retrieving data from Local DataTable (Action1, Action2,.. ActionN)


DataTable("ColumnName", dtLocalSheet)

'If retrieving data from Global DataTable (dtGlobalSheet)


DataTable("ColumnName", dtGlobalSheet)

Therefore, we can now create 2 statements using the syntax above to retrieve our user
name and password:

DataTable("UserName", dtLocalSheet)
DataTable("Password", dtLocalSheet)
Before we create our script, we must first tell QTP to run the test from all rows in the
Local DataTable. In Keyword view, right-click Action1 then click Action Call Properties:

Right-Click Action1

In the Run Tab of Action Call Properties window, select “Run on all rows”. A Dialog
will popup mentioning what we discussed in the beginning of this post, about ending our
iteration where the first step in our process begins.

Action Call Properties Window


Close the dialog, then click OK to save the settings we made under Action Call
Properties. We are now ready to create our script which will take data from each row and
test each UserName/Password combination. Below will be the steps in our process:

1. Launch application
2. Enter UserName/Password from DataTable and click Login
3. Verify if the Find Flights page appears
4. If Find Flights page appears, iteration passed.
5. Return to Home Page and start Step #2
'Step 1
If DataTable.LocalSheet.GetCurrentRow = 1 Then
SystemUtil.Run "iexplore.exe", "http://newtours.demoaut.com"
End If

After executing the above code, or manually launching the application, execute the below
steps:

'Parameterization Block:
With Browser("title:=Welcome: Mercury Tours", "index:=0")
'Step 2
'Parameter 1: UserName
.WebEdit("name:=userName").Set Datatable("UserName",
dtLocalSheet)
'Parameter 2: Password
.WebEdit("name:=password").Set Datatable("Password",
dtLocalSheet)
.Image("name:=login").Click
End With

'Step 3
'If Find a Flight page appears, go back to Home
If Browser("title:=Find a Flight: Mercury Tours:",
"index:=0").Exist(10) Then
'Step 4
Reporter.ReportEvent micPass, "Iteration " &
DataTable.LocalSheet.GetCurrentRow, _
"UserName: " & Datatable("UserName", dtLocalSheet) & "
is valid"
Browser("title:=Find a Flight: Mercury Tours:",
"index:=0").Link("text:=Home").Click
Else
'Step 5
'Else, fail the iteration and return to the Home page
Reporter.ReportEvent micFail, "Iteration " &
DataTable.LocalSheet.GetCurrentRow, _
"UserName: " & Datatable("UserName", dtLocalSheet) & "
is invalid"
Browser("title:=Sign-on: Mercury Tours",
"index:=0").Link("text:=Home").Click
End If

Once the above script ends its execution, your test results should look like this:
Execution Results

This topic covered a very high-level process of parameterization, but I hope it gives you a
good idea how this process can be enhanced and adapted to your application. The next
topic in Parameterization will cover Excel Spreadsheets and a few tricks that we can use
for successfully driving different sets of data to our AUT.

QTP: Parameterization with Excel


February 5, 2010 · 18 comments

In the previous article, we parameterized a test for a Login process with the help of
QTP’s Local DataTable. This topic covers the same concept with the help of an (external)
Excel file. The process will remain the same, but how we extract data differs. If you are
looking to understand Parameterization concepts and need a quick introduction, I would
recommend you to read the following article: Introduction to Parameterization with
QTP’s Local DataTable

Before we start the process of extracting data from Excel, and using the extracted data in
our automated process, we must first understand the Excel Automation object. Before
that even, we must understand the CreateObject function. The CreateObject function
creates and returns a reference to an Automation object1. In other words, usage of
CreateObject in terms of Excel will return the reference of Excel’s Automation object.
This reference will enable us to use Excel’s methods for data retrieval. Below is the
syntax of CreateObject:
Set Var = CreateObject(servername.typename [, location])

The Set keyword is used here because we have to bind out variable to an object. The Set
statement assigns an object reference to a variable or property, or associates a procedure
reference with an event2. We can use the syntax above in terms of Excel and create a
reference object that will hold methods of the Excel application:

Dim xlApp 'Excel Application Automation Object Reference

Set xlApp = CreateObject("Excel.Application")

Next, we will create a reference to the Excel WorkBook, which is the file that we will
open to retrieve data from. The workbook we’re working with is located in the root
folder: C: and its name is TestFile.xls. Thus, we will substitute the
pathNamefileName in our code below:

Dim xlBook 'Reference to the workbook located in C:

'Set varExcelWorkBook = ExcelObjectReference.WorkBooks.Open("File")


Set xlBook = xlApp.WorkBooks.Open("C:TestFile.xls")

Next, let’s create a reference to the Excel Spreadsheet (Sheet1, Sheet2, Sheet3..) which
contains the data we need to drive our parameterized script. Our data is contained in
Sheet1 of our workbook, thus, we will use it in our code below:

Dim xlSheet 'Reference to Sheet1

'Set varExcelWorkSheet = varExcelWorkBook.WorkSheets("Sheet")


Set xlSheet = xlBook.WorkSheets("Sheet1")

Below is a snapshot of the spreadsheet, with headings in Row 1 and data starting from
Row 2:

To retrieve the number of rows and columns used in the table, we will use the code
below:

'Total Rows
iRows = xlSheet.UsedRange.Rows.Count

'Total Columns
iCols = xlSheet.UsedRange.Columns.Count
Lastly, we will retrieve the data from Excel:

'First UserName is stored in the first column (Column A), second Row
(A2) of the spreadsheet
sUserName = xlSheet.Rows(2).Columns(1).Value

'First Password is stored in the second column (Column B), second Row
(B2) of the spreadsheet
sPassword = xlSheet.Rows(2).Columns(2).Value

I think we have covered the concepts needed to parameterize our script directly from an
Excel file. Now, let’s use the same example we did in the previous article to parameterize
the Login process for Mercury/HP’s demo AUT.

1. Launch application
2. Enter UserName/Password from DataTable and click Login
3. Verify if the Find Flights page appears
4. If Find Flights page appears, iteration passed.
5. Return to Home Page and start Step #2
'Step 1: Launch Application
SystemUtil.Run "iexplore.exe", "http://newtours.demoaut.com"
'Step 2: Enter UserName/Password from DataTable and click Login

'Retrieve UserName and Password from "iRow" rows and columns A & B
sUserName = xlSheet.Rows(iRow).Columns(iUserNameCol).Value
sPassword = xlSheet.Rows(iRow).Columns(iPasswordCol).Value

'Parameterization Block:
With Browser("title:=Welcome: Mercury Tours", "index:=0")
.WebEdit("name:=userName").Set sUserName 'Parameter 1:
UserName
.WebEdit("name:=password").Set sPassword 'Parameter 2:
Password
.Image("name:=login").Click
End With
'Step 3: Verify if the Find Flights page appears

If Browser("title:=Find a Flight: Mercury Tours:",


"index:=0").Exist(10) Then
'code
End If
'Step 4: If Find Flights page appears, iteration passed.

If Browser("title:=Find a Flight: Mercury Tours:",


"index:=0").Exist(10) Then
Reporter.ReportEvent micPass, "Iteration " & iRow-1, "UserName: " &
sUserName & " is valid"
Else
Reporter.ReportEvent micFail, "Iteration " & iRow-1, "UserName: " &
sUserName & " is invalid"
End If
'Step 5: Return to Home Page and start Step #2

If Browser("title:=Find a Flight: Mercury Tours:",


"index:=0").Exist(10) Then
Browser("title:=Find a Flight: Mercury Tours:",
"index:=0").Link("text:=Home").Click
Reporter.ReportEvent micPass, "Iteration " & iRow-1, "UserName: "
sUserName & " is valid"
Else
Reporter.ReportEvent micFail, "Iteration " & iRow-1, "UserName: "
&sUserName& " is invalid"
Browser("title:=Sign-on: Mercury Tours",
"index:=0").Link("text:=Home").Click
End If

Steps 1-5
We can now combine all the 5 steps into a single code block:

'Steps 2-5

Dim xlApp, xlBook, xlSheet


Dim iRow, sUserName, sPassword
CONST iUserNameCol = 1 'UserName is in Column A
CONST iPasswordCol = 2 'Password is in Column B

Set xlApp = CreateObject("Excel.Application")


Set xlBook = xlApp.WorkBooks.Open("C:TestFile.xls")
Set xlSheet = xlBook.WorkSheets("Sheet1")

'iRow = 2 because data to be driven starts from Row #2


For iRow = 2 to xlSheet.UsedRange.Rows.Count

'Retrieve UserName and Password from "iRow" rows and columns A & B
sUserName = xlSheet.Rows(iRow).Columns(iUserNameCol).Value
sPassword = xlSheet.Rows(iRow).Columns(iPasswordCol).Value

'Parameterization Block:
With Browser("title:=Welcome: Mercury Tours", "index:=0")
'Step 2
.WebEdit("name:=userName").Set sUserName 'Parameter 1: UserName
.WebEdit("name:=password").Set sPassword 'Parameter 2: Password
.Image("name:=login").Click
End With

'Step 3: If Find a Flight page appears, go back to Home


If Browser("title:=Find a Flight: Mercury Tours:",
"index:=0").Exist(10) Then
Browser("title:=Find a Flight: Mercury Tours:",
"index:=0").Link("text:=Home").Click

'Step 4: Pass the iteration


Reporter.ReportEvent micPass, "Iteration " & iRow-1, "UserName: "
&sUserName& " is valid"
Else
'Step 5: Fail the iteration and return to the Home page
Reporter.ReportEvent micFail, "Iteration " & iRow-1, "UserName: "
&sUserName& " is invalid"
Browser("title:=Sign-on: Mercury Tours",
"index:=0").Link("text:=Home").Click
End If
Next

xlBook.Close
xlApp.Quit
Set xlSheet = Nothing
Set xlBook = Nothing
Set xlApp = Nothing

When the above code executes, the follow results will be populated in QTP:

Parameterization with Excel: Results

I hope this article will help automation developers create parameterization with Excel.
The concepts covered in this article are quite basic, but they should serve as a baseline to
creating parameterization through Excel which can give users more control over how
they data-drive their tests. In the coming articles, I will show how Excel can be used as a
data-source with performance that QTP’s DataTable just doesn’t provide.
QTP: Working With Multiple Windows Applications
After writing the article Working with Multiple Browser Applications with QTP, I
thought, there are several instances where automation developers have to work with
applications containing multiple windows, in a Standard Windows Environment. This
technique uses a similar methodology as demonstrated in the article for Web-based apps,
but the crux of this technique differs. It can be used by automation developers testing
most types of windows applications, and it contains concepts that are showcased in my
generic automation framework RelevantCodes[1]One, which will be released in the
coming few weeks.

With the help of this technique, regardless of how many windows applications are opened
through QTP, we would never have to keep track of the Window’s title or any of its
recognition properties (unless we want to). In other words, regardless of a window’s
dynamic nature, this concept will enable you to give the window a name of your choice,
and use that name to identify the window, instead of keeping track of changes in its
properties.

What this concept contains:

• LaunchAdd: Launch a new window and retain its reference throughout the test
cycle
• AddNew: Automatically add a new open window to the collection without you
having to specify its properties (see list of dependencies)
• AddCustom: Adds a custom window by specifying its properties as an array
• All identifiers stay intact until the test finishes.

View clsWindow.txt | Download clsWindow.zip | Download Demo v9.2 | Download


Demo v9.5

This concept contains 3 main methods, as described above. You can download the Class
clsWindow for complete documentation, but for a quick overview, please continue
reading.

First, and the one that may be used the most often is a method called AddCustom. It
enables users to add a window of their choice to the collection, with the name they want
to specify. From that point onwards, regardless of the number of changes that particular
window goes through, it will not be required to update its properties. The name you give
the window can be used throughout the test cycle. Below is the code snippet for
AddCustom:

Public Sub AddCustom(arrPropertyValue, sName)


Dim lngHwnd

Me.sName = sName
Me.arrPropertyValue = arrPropertyValue
'Retrieve the handle of the specified window
lngHwnd = GetCustomWindowHwnd()

'If the handle is valid, then add it to the global collection


If lngHwnd <> -1 Then
colObject.Add sName, Window("hwnd:=" & lngHwnd)
If Not oDict.Exists(lngHwnd) Then
oDict.Add lngHwnd, lngHwnd
End If
End If
End Sub

Next is a method called LaunchAdd, which is dependent upon


GetRecentlyOpenWindowHwnd. This will enable you to automatically add a newly
launched window to the collection, with the name you specify:

Public Sub LaunchAdd(sFilePath, sName)


Dim lngHwnd

Me.sFilePath = sFilePath
Me.sName = sName

'Retrieve the window handle of the recently launched window


lngHwnd = GetRecentlyOpenWindowHwnd()

'If the handle is valid, then add it to the global collection object
If lngHwnd <> -1 Then
colObject.Add sName, Window("hwnd:=" & lngHwnd)
If Not oDict.Exists(lngHwnd) Then
oDict.Add lngHwnd, lngHwnd
End If
End If
End Sub

Private Function GetRecentlyOpenWindowHwnd() 'As Integer


Dim sFilePath, sName, oDesc, oParent, mHwndDict, x, iTimeElapsed

sFilePath = Me.sFilePath
sName = Me.sName

GetRecentlyOpenWindowHwnd = -1

On Error Resume Next

'Create a description object


Set oDesc = Description.Create

'oParent holds references to all the open windows


Set oParent = Desktop.ChildObjects(oDesc)

'Scripting.Dictionary: holds all open windows' handles


Set mHwndDict = CreateObject("Scripting.Dictionary")

'Loop until all the handles are successfully added to the


collection
For x = 0 to oParent.Count - 1
mHwndDict.Add oParent(x).GetROProperty("hwnd"), x
If Not oDict.Exists(oParent(x).GetROProperty("hwnd")) Then
oDict.Add oParent(x).GetROProperty("hwnd"),
oParent(x).GetROProperty("hwnd")
End If
Next

'Launch the target application


SystemUtil.Run sFilePath

'Loop max 10 seconds for the window to open


Do
Set oParent = Desktop.ChildObjects(oDesc)
For x = 0 to oParent.Count - 1
Select Case oParent(x).GetTOProperty("micclass")
Case "Window", "Dialog"
If Not
mHwndDict.Exists(oParent(x).GetROProperty("hwnd")) Then
GetRecentlyOpenWindowHwnd =
oParent(x).GetROProperty("hwnd")
Exit Do
End If
End Select
Next
Wait(1)
iTimeElapsed = iTimeElapsed + 1
Loop Until iTimeElapsed = 10

Set oDesc = Nothing


Set oParent = Nothing
Set mHwndDict = Nothing

On Error Goto 0
End Function

Lastly, and a tricky one is AddNew. This will automatically add any new open window
after LaunchAdd has been executed. Like the other 2 methods, this method will also
enable preservation of a window’s property until the end of the test.

Public Sub AddNew(sName, iTimeOutBeforeWindowOpens)


Dim oDesc, oParent, x, iTimeElapsed, lngHwnd

'Set default application timeout


If iTimeOutBeforeWindowOpens = "" Then
iTimeOutBeforeWindowOpens = 1
End If

'Create a Description Object


Set oDesc = Description.Create

'oParent holds all open windows


Set oParent = Desktop.ChildObjects(oDesc)

'Wait iTimeOutBeforeWindowOpens number of seconds


'Default iTimeOutBeforeWindow Opens = 1
Wait(iTimeOutBeforeWindowOpens)

'Loop for 5 seconds


'If within 5 seconds, a new unadded window is found, the window will
' be added to the collection and this procedure will end.
Do
'Create a new collection
Set oParent = Desktop.ChildObjects(oDesc)

'Loop for all objects in the collection and find a one that does
'not exist in the global dictionary: colWindows
For x = 0 to oParent.Count - 1
If Not oDict.Exists(oParent(x).GetROProperty("hwnd")) Then
lngHwnd = oParent(x).GetROProperty("hwnd")
oDict.Add lngHwnd, lngHwnd
colObject.Add sName, Window("hwnd:=" & lngHwnd)
Exit Do
End If
Next
Wait(1)
iTimeElapsed = iTimeElapsed + 1
Loop Until iTimeElapsed = 5 'This timeout can be minized to 1, if
desired
End Sub

Você também pode gostar