QTP Tutorial 25-18

63
QTP Tutorial #25 – What is Descriptive Programming and How to Connect to External Data Sources Using QTP? In this tutorial you will learn what descriptive programming in QTP is, and how to connect to external data sources like database and MS Excel sheets using QTP. Descriptive programming in QTP Descriptive programming is a mechanism for creating tests where you use “Programmatic description” of objects instead of recording them. Using this technique QTP can be made to identify objects that are not in the repository. There are 2 variations of descriptive programming: 1) Static Descriptive programming 2) Dynamic Descriptive programming Static Descriptive programming Static method is when you try to access an object by using a set of properties and values directly in a VB statement. Syntax: TestObject(“Property name1:=property value”,”property name 2:=property value”,….n) This is how you use it: 1 Browser(“creationtime:=0”).Page(“title:=Google”).WebButton(“name:=Google Search”) Dynamic Descriptive programming This works by creating a description object. Look at the following example to create a webButton object.

description

qtp

Transcript of QTP Tutorial 25-18

QTP Tutorial #25 – What is Descriptive Programming and How to Connect to External Data Sources Using QTP?In this tutorial you will learn what descriptive programming in QTP is, and how to connect to external data sources like database and MS Excel sheets using QTP. 

Descriptive programming in QTP

Descriptive programming is a mechanism for creating tests where you use “Programmatic description” of objects instead of recording them.

Using this technique QTP can be made to identify objects that are not in the repository.

There are 2 variations of descriptive programming: 1) Static Descriptive programming2) Dynamic Descriptive programming

Static Descriptive programmingStatic method is when you try to access an object by using a set of properties and values directly in a VB statement.

Syntax: TestObject(“Property name1:=property value”,”property name 2:=property value”,….n)

This is how you use it:

1Browser(“creationtime:=0”).Page(“title:=Google”).WebButton(“name:=Google Search”)

Dynamic Descriptive programmingThis works by creating a description object.  Look at the following example to create a webButton object.

1

2

Set Testdesc=description.create

Testdesc(“micClass”).value= “webButton”

micClass refers to the predefined classes in QTP. The values you can assign can be webbutton, weblist etc.

In QTP 10 micClass values are case sensitive but in QTP 11 onwards they are not. If you write webbutton in QTP 10 it will fail. You will have to write webButton. But the same webbutton will pass in QTP 11.

You can extract all the objects of a certain class in a page by using the following statement:

1

2

Set ObjectList=Browser(“creationtime:=0”).Page(“title:=*”).ChildObjects(Testdesc)

Msgbox ObjectList.count

The above set of statements will extract all the buttons on a page and store them in the ObjectList object.

The versatility of using descriptive programming is that these lines of code will work on any open page. You can open google.com in your browser and it will count how many buttons are on that page. It will work exactly the same way if you had amazon.com or any other site open.

This is because we have the name of the title of the page set to * which is a regular expression.

So you can see, how we can write code that can be used in more than one occasions by not hard coding the property values and by creating the objects at run time.

Let us take our example a little further. Say I am trying to print the names of all the webbuttons on the page one after the other.

If there are 4 buttons in a page, you can access each one of them the following way:

Msgbox ObjectList (0).GetRoProperty(“name”) –This will print the name of the first button.Msgbox ObjectList (1).GetRoProperty(“name”)Msgbox ObjectList (2).GetRoProperty(“name”)Msgbox ObjectList (3).GetRoProperty(“name”)

Note that:

The index of the child objects starts from 0 Since the object achieves its properties at runtime, we use the GetRoProperty method to

retrieve the same.

We can change the above code to work for any number of Buttons in the page by using a ‘For loop’ and repeating the statements within the ‘For block’ until it reaches the end of the object count.

1For i=0 to ObjectList.count -1 to Step 1

Msgbox ObjectList (i).GetRoProperty(“name”)

2

3Next

Using a ‘For loop’ is better because in this case you don’t need to know how many objects are in your description object.

Couple of points to note:

You will need practice to master descriptive programming. No matter how many examples you look at and understand, you will need hands on experience to really work with it.

As a tester you are not expected to know how the objects are coded into your AUT and what values they are set to. So use ObjectSpy from time to time to choose the right properties to view the properties.

The test results will indicate that the test object was created dynamically during the run session using a programming description or the ChildObject methods.

Connecting to some commonly used external data sources from QTP:

There will be many instances while you are preparing your tests that you will have to connect to an external DB or some other data sources. Once connected, you also will have to move data to and from these apps to QTP and vice versa. Though it is beyond the scope of these articles to provide a complete guide for working with external interfaces, we will look into a few that are most commonly used.

Database Connection To connect to a database we typically use an ADO connection object. ADO is Microsoft’s ActiveX Data Objects.

The following are the steps to be followed:a) Create a DSN. Please refer to the database checkpoint tutorial to see how this is done or create one from the control panel.b) Create a connection object:Setconn=CreateObject(“ADODB.connection”)c) Create a record set object. The record set object holds the results of the query that we are going to run.Set rs=CreateObject(“ADODB.RecordSet”)d) Open the connection object and run the query:conn.Open “DSN=testDB2;UID=swatiseela;pwd=testing@123”rs.Open “Select * from abc”,conne) All the query results can now be accessed using the “rs” object.f)  For example, if you want to get the count of the rows returned, you can users.getrowsg) For example, the table has 2 rows and 3 columns(a,b,c) you can access the values as follows:Msgbox rs.fields(0).aMsgbox rs.fiels(0).b

Msgbox rs.fields(0).ch) You can use a loop statement if there are too many values to be accessed.i)  Some of the functions that record set object can use are: rs.move, rs.movenext, rs.getrows, rs.close, rs.open, etc.

Let us look at all the code at one time:

12345678910111213

Set conn=CreateObject(“ADODB.connection”)Set rs=CreateObject(“ADODB.RecordSet”)conn.Open “DSN=testDB2;UID=swatiseela;pwd=testing@123”rs.Open “Select * from abc”,connmsgbox  rs.getrowsMsgbox rs.fields(0).aMsgbox rs.fiels(0).bMsgbox rs.fields(0).cMsgbox rs.fields(1).aMsgbox rs.fiels(1).bMsgbox rs.fields(1).crs.closeconn.close

Connecting to MS Excel sheets

We all know that when we open an excel application, the entire file is a workbook which has sheets with columns and rows where we put in the data.

The following is the code and comments to help you understand how it is done.

12345678910111

‘Create an excel application objectSet excelobj = CreateObject(“Excel.Application”)‘Set it to visible, otherwise it will be visible in the task manager but you will not be able to view it but it continues to work in the backgroundexcelobj.visible = true‘Opens a workbook at the path speficified. If you need to open a new workbook, use excelobj.workbooks.Addexcelobj.workbooks.Open(“C:\Users\Swati\Desktop\QTP\test.xls”)‘Sets the current sheet as i. the sheet number starts from 1i=1Set sheet1 = excelobj.activeworkbook.sheets(i)‘write to a cell in sheet 1. The cell is row 8 column 4, D8.excelobj.activeworkbook.sheets(1).cells(8,4) = “Test QTP Write to cell”‘To get the data from sheet2 cell ID C6testretrurnval = excelobj.activeworkbook.sheets(3).cells(6,3)‘save changesexcelobj.activeworkbook.save‘close the workbook

2131415161718192021

excelobj.activeworkbook.close‘Close Excel applicationexcelobj.quit‘Clear memorySet excelobj = nothing

Apart from the above functions we have the following ones we can use depending on your need.

excelobj.activeworkbook.sheets.add – To add a new sheet excelobj.activeworkbook.sheets(i).delete – To delete a sheet with index i excelobj.activeworkbook.sheeets(i).name = “Name of your choice” – To change the

name of a sheet with the index i. x=excelobj.activeworkbook.sheets.count – to get the count of how many sheets are in a

workbook excelobj. activeworkbook.saveas “CompletePathWithNewName.xls” – to save the

workbook under a new name

QTP Tutorial #22 – Using QTP Object RepositoriesObject Repositories and Object Repository Manager

Today’s topic is Object repositories. In the previous articles, we have discussed how QTP identifies and stores objects in a warehouse, the OR. We also have seen how the object properties appear in the OR. To quickly recap, we will take a look at the OR screen. You can launch it from

your current test by clicking on the icon or from the “Resources->Object Repository” option.

It launches the  following Object repository dialog box:

Points to note here:

1. The objects are stored in a hierarchical manner.2. This is a local repository that contains the objects for Action1.3. If the action had any checkpoints the same would have been available in this dialog to

edit.

We also have made multiple references to Shared ORs in our previous articles. Let us learn all about them.

A shared object repository stores objects in a file that can be accessed by multiple tests (in read-only mode).

One of the important aspects when planning your tests (or choosing a framework for your project) is to consider where and how you want your objects to be stored and how they have to be made available to the tester.

The following are some Object Repository types in QTP:

1. Local ORs- each action will have its objects stored in its local repository2. Shared ORs – all the actions will refer to a single read only OR3. Local and Shared ORs- an action can use both local and multiple shared ORs.

In one of our previous tutorial we talked about how objects get selected if a certain action has both Shared OR and Local OR, multiple shared ORs, etc.

We will see how a shared OR is created and how we can move objects to and from a shared OR to local or vice versa.

To maintain ORs in your test there is a specialized Object Repository Manager that QTP provides. It can be accessed from the menu item “Resources->Object Repository Manager”.

Using ORM you can do the following:

Creating New Object Repositories Opening Object Repositories Saving Object Repositories Closing Object Repositories Managing Objects in Shared Object Repositories Managing Repository Parameters Modifying Object Details Locating Test Objects Performing Merge Operations Performing Import and Export Operations

In this example, we will see how to create a shared OR for a test, understand how it can be associated and see how the objects can be used.

To create a shared OR (.tsr) file, launch ORM. A new repository will open up or you can explicitly do so by using the option “File->New”.  Any OR is only as good as the objects it has. So the next step is obviously to add objects.

There are 3 ways you do that from here:

Method #1) Define Test objects. “Object->Define Test Object” – on choosing this option the following dialog appears:

In here, you can specify environment, Class, Name, Properties and Add the object to the repository. The screenshot can be a sample data you could enter.

Method #2) Add Objects: On choosing this option, the pointy hand gets active, QTP gets minimized and when you click on the object you wish to add, the following dialog shows up and you can add the object.

Method #3) Navigate and Learn:  This is the most interesting and most used way. As the name indicates, you just have to instruct QTP to ‘navigate and learn’, point to an object in your app and QTP automatically gets the objects depending on your filter settings. Choose this option

from the menu or hit F6, in the screenshot notice the little navigate and learn dialog on the top of the page. Now Hit the Learn button in the dialog and click on the page. Navigate as many pages and hit learn as many times as required. Once done, close the “Navigate and Learn” dialog.

The filter options are as follows:

I chose “All Object Types” from the dialog and clicked on the main gmail.com page, the following are the objects that get added to the OR:

Using any of the above ways create a shared ORM, add objects and save it.

There is another way objects can be added to a shared OR. It is from the local OR.

Open your test or create a new test. Gmail Login- our example. Launch the OR for this test. It looks like this:

I want to create a shared OR that contains the Email, password and Sign In objects. The “File” Menu has 2 options under it, “Export Local Objects” and “Export and Replace Local Objects”. You can use either one of these options.

If you use “Export Local Objects”, the local objects are exported to the specified shared object repository (a file with a .tsr extension). Your test continues to use the objects in the local object repository, and the new shared object repository is not associated with your test.

With “Export and Replace Local Objects”, the new shared object repository (a file with a .tsr extension) is associated with your test, and the objects in the local object repository are deleted.

Choose any of the options and choose the shared OR to export to.

Associating the shared Object Repository to your test

After you decide to use a shared OR for your test, create one and add objects to it, the tester has to explicitly include the .tsr file to the test to be able to use the objects in it.

To do so, go to “Resources->Associate Repositories”. The following dialog box opens up:

Click on the “+” sign. Choose the OR.  Once you choose it, all the actions that are available in your test will appear under the “Available Actions” box.

Select as many or as few as you would like. I just have one, so I am going to go ahead and choose it. Click OK when done.

On successful association, the shared OR will appear in the Resources pane if it is already visible or you can launch the same from “View->Resources” option.

If you want to remove the association, you can right click on the .tsr in the resources pane and select “Remove Repository from List” option. Or you can go to “Resources->Associated Repositories” menu option, select the shared ORM to remove and click on the cross sign.

For rules on how a shared OR and Local OR will work, please refer to our tutorial #8. Though there are many other features to ORM and OR, we will limit ourselves to what we have learned in this article as they are the most useful ones. The rest of them are very easy for any tester to figure out on their own once they read this article.

QTP Tutorial #24 – Using Virtual Objects and Recovery Scenarios in QTP TestsVirtual Objects in QTP

Do you see Object not found error while running QTP tests? Well, this is because during playback QTP can’t recognize non-standard objects. To solve this object recognition problem we use Virtual Objects. Using Virtual Object Wizard we can map these unrecognized objects to standard class which then can be used as standard object to record the test.

How to solve object recognition problem in QTP?

Example of Virtual Object:Here is a scenario: I am recording a test on a Microsoft word document. I activate the already opened MS word doc and I click on any of the icons in the top menu. For example, I click on “Format Painter”. The code that gets recorded into QTP is:

Window("Microsoft Word").WinObject("NetUIHWND").Click 132,120Window("Microsoft Word").WinObject("NetUIHWND").Click 672,101

In cases like this we would go for a virtual object. By definition, a virtual object is an object that is recognized by QTP as non-standard but is instructed explicitly by the tester to behave like a standard object.

Virtual Object Wizard Steps:

Step #1) Go to the menu option “Tools->Virtual Objects-> New Virtual Object” and click “Next” in the following window.

Before you hit “Next” take a minute the read what this wizard will do.

Step #2) Here you will find a list of classes. You can choose any class depending on how the object in your application is behaving like. In our case, the “Format Painter” Icon is more like a button. So I am going to choose “Button” from the list.

Step #3) In this screen you can mark the screen where the object is on your AUT. Click “Mark Object” and choose the object from your AUT.

Step #4) The width and height values for the marked object will be populated once the selection is made. Hit “Next”

Step #5) You can now configure the way in which you would want the selected object to be recognized with reference to its parent. As you can see, you have a choice to see identify it based on its parent alone or the entire hierarchy. I am just going to keep the default values and click “Next”

Step #6) Give your virtual object a name and add it to a collection (nothing but a consolidated list of Virtual objects). I keep the default  values and click “Finish”

This completes the process for creation of a Virtual object.

Step #7) Go to “Tools->Virtual Objects->Virtual Object Manager”. Here you can see all the collections that are available and the objects within them.

Clicking on “New” will take you back to the creation process that we have just seen. You can delete a collection using the “Delete” button.

Once you are done creating the virtual object, repeat the recording process on your AUT for the same object. This is how the code looks:

Window("Microsoft Word").WinObject("NetUIHWND").VirtualButton("button").Click

Now you will be able to perform all the operations on this VirtualButton that you can on a standard button object.

A few points to note:

1) This feature is not available for Analog and low level recording modes.

2) From the example you can see that the virtual object completely relies on the width and height factors, so it is not highly reliable.

3) To disable QTP from recognizing the virtual objects while recording, choose the option “Disable recognition of virtual objects while recording’ under “Tools->Options->General”.

Recovery Scenario in QTP

At times when you are trying to login to your Gmail account, assume a pop-up window comes up and you will be asked to confirm your security information. This does not happen every time you login. If your test is to login to Gmail account and as soon as you enter the user ID, password, hit

the Sign In button and if your QTP test is expecting to arrive at your inbox your test is going to fail if the security information screen comes up randomly.

To handle cases like this we use the ‘Recovery Scenarios”.

Steps to create Recovery Scenario in QTP:

Step #1) Go to “Resources -> Recovery scenario manager” , click on the “New Scenario” icon.

Step #2) Click Next

Step #3) The trigger for this to start could be one of the following options. Choose according to your scenario. In our case I will choose, Pop-up window. The other options are self explanatory.

Step #4) Using the “Pointed hand” option, choose the window that you would want to add.

Step #5) Define the recovery option by clicking on the “Next” icon below:

Step #6) Choose one from the list. I am going to choose “Keyword or mouse operation”. The options in this screen are really easy to understand. So choose accordingly.

Step #7) I am going to go with the default settings and click Next. The recovery operation gets added to the list. If you need to add more than one recovery operation you can keep the corresponding checkbox checked and click Next. It will take you back to the screen in Step number: 5. Or if you are done, you can simply uncheck the checkbox and click on “Next”. That is what I am going to do.

Step #8) Now you will have to define the post recovery operations.  All the options are as their names indicate. I am going to choose “Proceed to next step”. Click Next

Step #9) Enter the scenario name, description and click Next

Step #10) It provides a gist of your scenario. As you can see, there are 3 parts to a recovery scenario. The Trigger, Recovery operation and post recovery operations. You can choose to add this scenario to the current test or to all tests by choosing the relevant checkboxes. I am going to

keep them unchecked at this point because I want to show how a tester can associate them to a test explicitly. Click “Finish”

Step #11) The scenario we just created will appear in the list. Save and close.

Step #12) Associating the recovery scenario. Open a test, in the “Resources” pane, right click on “Associated Recovery scenarios”, right click and choose “Associate recovery scenario”. Browse for the scenario and click “Add Scenario”. The chosen scenario will appear in the list in the Resources pane.

Step #13) Also, you can go to “File->Settings->Recovery” and add the scenarios you would like. Here you can also choose the options as to how often you would like it to run. You can choose to run it, On Error, On Every Step or Never.

Step #14) The extension for a recovery scenario file is “.qrs”

This concludes our discussion on Virtual Objects and Recovery scenarios. I would recommend the tester to use various combinations of Trigger, Recovery and post recovery operations when practicing the recovery scenarios.

QTP Tutorial #23 – QTP Smart Object Identification, Sync Point, and Test Result AnalysisIn this QTP tutorial we will learn – Smart Object identification, adding Synchronization point, Running a test and viewing the results, and Silent Test runner.

Smart Identification:

Assume a situation when no object matches or multiple objects match the recorded description for an object during run time, how does QTP handle it?

QTP has a mechanism in place for cases exactly like this. If the recorded description does not enable QTP to identify the specified object in a step, and a smart identification definition is defined (and enabled) for the object, QTP tries to identify the object using “Smart identification”.

Let us see how this works with some examples.  For every object there are Primary Properties and Secondary properties.

Example 1: Object with the recorded description is not found.

On a page there was a button and the following are properties:a) Primary: Nameb) Secondary: Abs x,y

While recording the “Name” property was “Login ID”. Due to some changes to the application, the “Name” property is now changed to “User ID”. In this case, QTP will find a button with a different description and it should fail if it considers the primary properties alone.

But in cases like this when the primary properties don’t match then it checks the secondary ones and if they match it recognizes the object. In this case, it is going to recognize the button by its X and Y co-ordinates.

Example 2: QTP was supposed to find a page X and there are 2 pages with similar browser settings.

In this case too, it tries to use the “name” or other properties to find the right page/pages and works accordingly.

The above 2 are examples of cases where QTP engages the smart identification mechanism.

The Test results will also show if a step employed Smart identification to run successfully. If QTP cannot find the object despite Smart Identification, then the test fails.

For most of the objects, QTP provides a default Base filter properties (Primary) and Optional filter properties (Secondary) that it checks if we enable Smart identification for them. The user does have an option to edit what properties to consider too. To do so, go to “Tools->Object Identification”. Choose the relevant Environment from the drop down and choose the Object Class. Once you chose it, check the “Enable Smart Identification” and click “Configure”.

Click Add or Remove

Select the properties as required:

Make your selection and Click OK when done.

The above process will ensure that the next time it has difficulty identifying an object of this class, it will employ smart identification to do so.

Also, for most of the objects “Smart identification” is turned ON by default. You can see where this is the case for a certain object by accessing it in the OR under “Additional details” part of its object properties.

It is set to “True” if enabled and “False” if disabled.

You could also choose to enable or disable Smart identification entirely for a test run. Choose “File->Settings->Run->Disable Smart Identification during the run session” option.

Synchronization point:

Consider this program,

SystemUtil.Run "iexplore.exe", "http://www.gmail.com"

Browser("Gmail: Email from Google").page("Gmail: Email from Google").Sync

Browser("Gmail: Email from Google").Page("Gmail: Email from Google").WebEdit("Email").Set "swatiseela"

Browser("Gmail: Email from Google").Page("Gmail: Email from Google").WebEdit("Passwd").SetSecure "sfgs686898"

Browser("Gmail: Email from Google").Page("Gmail: Email from Google").WebButton("Sign in").Click

Browser("Gmail: Email from Google").Page("Gmail - Inbox").Link("Sign out").Click

In an ideal world, as soon as you hit the “Sign in” button in the gmail login page, the “Inbox” should get displayed without any delays. That means, the state of the application is ready for the last statement in our example to be executed immediately after the last but one statement runs.

But in real time, due to many reasons applications don’t always load at the same pace. If we do not instruct QTP to wait a certain while before it moves on. More specifically until an object attains a certain state.

A synchronization point is used to instruct QTP to wait until a particular object property achieves the value you specify.

On inserting a sync point a “Wait Property” statement is inserted into the test.

Browser("Gmail: Email from Google").Page("Gmail - Inbox"). Link("Sign out").WaitProperty “Visibile”,true,20

So your new program is going to look something like this: (line #6 below)

SystemUtil.Run "iexplore.exe", "http://www.gmail.com"

Browser("Gmail: Email from Google").page("Gmail: Email from Google").Sync

Browser("Gmail: Email from Google").Page("Gmail: Email from Google").WebEdit("Email").Set "swatiseela"

Browser("Gmail: Email from Google").Page("Gmail: Email from Google").WebEdit("Passwd").SetSecure "sfgs686898"

Browser("Gmail: Email from Google").Page("Gmail: Email from Google").WebButton("Sign in").ClickBrowser("Gmail: Email from Google").Page("Gmail - Inbox"). Link("Sign out").WaitProperty “Visible”,true,1000

Browser("Gmail: Email from Google").Page("Gmail - Inbox").Link("Sign out").Click

It can be inserted while recording using the menu option “Insert->Synchronization Point”.  Choose the Object to insert the sync point.

Enter the value as required:

This is the statement that gets inserted:

Browser("Gmail - Inbox").Page("Gmail - Inbox").Link("Sign out").WaitProperty "visible", true, 10000

Running a test

1) Automation->Run or F5 typically runs the entire test.

2) You can run a part of the test by choosing “Automation->Run Current Action” option

3) You can run a test from a certain point in your test by choosing “Automation->Run From Step” option.

4) As soon as you choose any of the above ways to run a test, you will be promoted to choose the location where you would like the test results to be stored. You can choose the folder by choosing the first option in which case, the results will be stored for every instance of the test run. But if you choose the next option, temporary folder, the results get overwritten and only the latest test run result will be stored in the folder chosen. In terms of memory, it is advisable to use the second option while testing your QTP test. Unless you want every test run results, do not choose the first option because obviously it is going to use up a lot of space.

5) Input parameters:  If the test input parameters were defined for this test, this tab is the place where you provide them.

6) You can also run a couple of tests all at once in a batch. QTP has a “Batch Runner” tool. It is also an external tool just like a “Password encoder tool” that we discussed earlier.

7) To launch go to “Programs > QuickTest Professional > Tools > Test Batch Runner”.

Create a batch (.mtb) using .

8) Once creating a list is done, run the batch using  icon. After the batch run is complete, you can view the results for each test in its default test results folder (<test folder>\res#\report).

Test results:

In our articles so far, whether we are discussing data table iteration, checkpoints, smart identification or in general the test step run , the Test results is the place you get to see whether something was successful or not.

Apart from the above, the test results can hold the screenshot of your AUT when a failure occurs. This depends on the settings at “File->Settings->Run”.

The tester can print and export test results.

To make test results more understandable the user can write his comments into the test results.

For example, if a certain condition fails in your test you might want to write in the test results that “Did not work for the value X”. You can do so by using the “reporter.reportevent” statement. The following is the syntax:

Reporter.Reportevent(Event Status,Reporter step name, details)

Event status: MicPass, MicFail,MicWarning,MicDetail, the next two parameters can be any text that helps include further detail.

If this is my statement and I run it:

reporter.ReportEvent micPass,”Swati’s First Step”,”Passed coz I told it to pass …”

The test results are going to look like this: (click to enlarge image)

Transactions:

Since this is not a very widely used feature, I am going to do a high level introduction here.

Typically, a test is divided into transactions when you have to measure how long it takes to run a certain section of it.

It is also used when a QTP test is to be used by Load Runner or Business Process Monitor. In either of these cases, your test has to be recorded in terms of a transaction and anything outside of it will be ignored.

You can start a transaction from QTP using “Insert->Start Transaction”. Give it a name, choose if you want it before or after the current step and choose OK.

Services.StartTransaction “TransactionTest” – Gets inserted. Now I will record a login into Gmail.com.

Once you are done recording. Choose “Insert->End Transaction”. Click OK.

Services.EndTransaction “TransactionTest” – gets inserted.

This is the code:

Now I will run this test. Let us see how the test results look. The results will show a summary in terms of time taken to finish the transaction.

Silent Test runner:

Another tool that QTP provides is the Silent Test runner. This enables the tester to run his test without having to launch QTP. It also helps simulate QTP runs from load runner and verify it compatibility with the same.

It will not work if QTP is already open and another test is running via it.

Use Start > Programs > QuickTest Professional > Tools > Silent Test Runner menu command to invoke it. Select the test and click “Run Test”

This is how it looks while running the test:

QTP Tutorial #20 – Parameterization in QTP – Part 2

In part 1 of this QTP Parameterization tutorial we explained Datatable Parameterization with example. In this QTP tutorial let’s focus on remaining three parameterization techniques:

2) Random number parameters3) Environment variable parameters4) Test/Action parameters

#2 – QTP Parameterization using Random Number

If a certain field needs to have any number within a certain range you can specify the same using QTP. In the Value configuration properties screen, select “Random number” and the following

options come up:

As you can see, the options are pretty self explanatory. The range can be set and how many times during a particular iteration run or a test run should this value be generated can be programmed here.

Let us just keep the default settings and click OK and see the line of code that gets inserted.

Browser("Google").Page("Google").WebEdit("q").Set RandomNumber("p_Text")

In real time, this is a very useful feature that can help the tester automate the scenarios in which the numeric range of data needs to be verified.

#3 – QTP Parameterization using Environment Variables

Environment variable is a value that remains the same throughout a test run unless explicitly changed by the program.

3 types of environment variables:

1. User defined internal

2. User defined external3. Built in

We will start with built in variables because that is the simplest.

Built in variables are created by QTP itself and contain information about the test path, operation system etc. These are read only and hence can only be used by the user as they are.

Some examples are TestIteration, OS, OSVersion etc. The usage is similar to the usage of any other variable. For example in the second iteration of a test you want to display a custom message, this is how you can do it:

1

2

3

4

If TestIteration=2

Msgbox “Cusotm message: Take a break!”

<….Code….>

End if

Next, let us try to parameterize a certain value with an environment variable.

From the above screen, you can see that the type is read only and we are only able to create a user defined- internal environment variable.

Click on the “Name” Drop down box:

Even though we have not created any environment variables in this test so far there are many of them available in the drop down to be used.

Select any one of them:

It shows that the variable is a built-in and read only. So this shows how we can use a built in variable.

But if we need a new one, enter a new name, say PV assign 0 and save it:

Let us first accept the default values and enter a “0” in the value field and click OK. The following is the line of code that gets inserted:

Browser("Google").Page("Google").WebEdit("q").Set Environment("PV")

Since we inserted an E.V. it is obvious that the value of PV is going to be 0 throughout the test. The next time you are trying to parameterize anything else with an environment variable within the test this one will be available in the list.

User defined – external:  In case when we need to have an entire list of environment variables available for a test, the user has an option to create it externally and associate it to the test and make those variable available to this test.

Typically, this file is an .xml with the structure as follow and is available on your desktop:

<Environment><Variable><Name>First Name</Name><Value>Swati</Value></Variable><Variable><Name>Last Name</Name><Value>Seela</Value></Variable></Environment>

Once this is set, we can add this file to the test by going to “File->Settings->Environment” and selecting “User defined” from the drop down:

In the screen, you can see the option to add the file, so ahead and add it.

Alternately, if I need the variables in this test for another one, I can export them into a file by clicking on “Export” option.

So now that we know how to set and use environment variables, there is yet another use for these:

In case, we set the values for URL_env and Browser_env variables, then the record and run settings set overrun and no matter what you set there, it is going to consider the values that these variables contain.

#4 – QTP Parameterization using Action and Test Parameters

We know that a test in QTP but a call to an action. Input parameters for an action or test are nothing but the values that get supplied to them from else where in the test.

They could be:

1. Value(s) passed on while calling that action2. Return value of another action (Output parameters)3. A value that it gets from some top level action

Output parameters are the return values of an action that can be used later in the test.

The way these can be used to parameterize is as follows:

These can be used as a parameter by using the “Parameter” keyword.

If this is the statement that you need to parameterize so that the value you set is not a constant “swati” but a value that is the input value of an action that is already defined, say “OPFirstName”:

1Browser("Gmail: Email from

Google").Page("GoogleAccounts").WebEdit("FirstName").Set "swati”

This is how it is done:

1Browser("Gmail: Email from

Google").Page("GoogleAccounts").WebEdit("FirstName").Set Parameter(“OPFirstName”)

Also, if there is a output parameter that is already defined then you could also write something like:

1Parameter("TotalValue") = Browser("Gmail: Email from Google").Page("GoogleAccounts").WebEdit("FirstName")

Now let us see, how the i/p or o/p parameters can be set in the first place. Let’s start with an action.

You can define, modify, and delete input and output parameters in the Parameters tab of the Action Properties dialog box (Edit > Action > Action Properties or right-click an action and select Action Properties).

So, to call an action with the input parameters this is the statement that needs to be used:

1RunAction ActionName, IterationQuantity, Parameters

This concludes our parameterization. Out of all that we have discussed in these 2 articles, the one that we use the most is the data table option. So please take some time to write a test and run it with all the iteration options to get a grip on this topic.

QTP Tutorial #19 – Parameterization in QTP Explained with Examples – Part 1What is QTP parameterization?Sometime application does not accept the duplicate data records. In this case if you run same test script with fixed set of input data, application may throw an error due to data duplication. To avoid this issue, QTP provide ways to accept different test inputs to the test script. This process of providing different input values through external parameters is called as parameterization

Types of parameterization in QTPThe variable value can be or the parameter types can be:

1. Data Table parameters2. Test/Action parameters3. Environment variable parameters4. Random number parameters

In this QTP tutorial we will focus mainly on parameterization using Datatable. We will explain other types of parameterization methods in next tutorial.

Parameterization in QTP

Say you are trying to write a program that checks the login values for a couple of users on gmail.com.

The following is the code that you have for one user but you want the same to take different values each time. How do you do this?

Code to sign in to gmail for one user:

SystemUtil.Run "iexplore.exe", "http://www.gmail.com"Browser("Gmail: Email from Google").page("Gmail: Email from Google").SyncBrowser("Gmail: Email from Google").Page("Gmail: Email from Google").WebEdit("Email").Set "swatiseela"Browser("Gmail: Email from Google").Page("Gmail: Email from Google").WebEdit("Passwd").SetSecure "sfgs686898"Browser("Gmail: Email from Google").Page("Gmail: Email from Google").WebButton("Sign in").ClickBrowser("Gmail: Email from Google").Page("Gmail - Inbox").Link("Sign out").Click

Now, go to keyword view and click on the value column for the email id and password set statements.

Typical screen that comes up when you are trying to parameterize:

As you can see, the value can either be a constant, “swatiseela” in this case, the login ID.

Or if you choose the parameterize option then the corresponding fields in the screen get activated.

From this screen you can choose to parameterize the chosen value with either a value from the data table, environment variable or a random number. Since the most often used source is the datatable we will discuss that first.

Apart from these, you could use the input and output values of a certain action as a parameter for a value. We will discuss that too in a while.

Parameterization in QTP using Datatable with Example

Parameterization in QTP using ExcelI checked the parameter value ON and then the there is a location in Datatable field following the name.

Name: The corresponding column name in the data table from where the data needs to be taken. By default QTP will suggest a name. You have an option to keep it as suggested

or change it as needed.

Global Sheet:  This sheet of data is available to all the actions in a test.

Current action sheet or local sheet:  as the name suggests, it is the sheet of data that is available to a certain action.

I am going to multiple rows of data to the Global data sheet. This is where the password encoder tool comes in handy. You can put in encrypted values in your data sheet that you get from this tool.

This is how my data sheet looks like:

After parameterization this is how the code looks like:

SystemUtil.Run "iexplore.exe", "http://www.gmail.com"Browser("Gmail: Email from Google").page("Gmail: Email from Google").SyncBrowser("Gmail: Email from Google").page("Gmail: Email from

Google").WebEdit("Email").Set DataTable("SignInName", dtGlobalSheet)Browser("Gmail: Email from Google").page("Gmail: Email from Google").WebEdit("Passwd").SetSecure DataTable("GPassword", dtGlobalSheet)Browser("Gmail: Email from Google").page("Gmail: Email from Google").WebButton("Sign in").ClickBrowser("Gmail: Email from Google").Page("Gmail - Inbox").Link("Sign out").ClickBrowser("Gmail: Email from Google").page("Gmail: Email from Google").SyncBrowser("Gmail: Email from Google").Close

You will see in the above code that the values for the email ID and password are taken from datatable.

This code will run for all the 4 rows of data in the global sheet if in the following screen I set the option “Run on all rows” ON:

Just in case, if you don’t want to use the above screen to decide how many rows the code needs to be executed for you can do so programmatically. For that, you need to select the option “Run one iteration only” on the above screen and write the code the following way:

for i=1 to datatable.GetRowCountSystemUtil.Run "iexplore.exe", "http://www.gmail.com"Browser("Gmail: Email from Google").page("Gmail: Email from Google").Syncdatatable.SetCurrentRow(i)varName=datatable.value("SignInName")varPwd=datatable.Value("GPassword")Browser("Gmail: Email from Google").page("Gmail: Email from

Google").WebEdit("Email").Set varNameBrowser("Gmail: Email from Google").page("Gmail: Email from Google").WebEdit("Passwd").SetSecure varPwdBrowser("Gmail: Email from Google").page("Gmail: Email from Google").WebButton("Sign in").ClickBrowser("Gmail: Email from Google").Page("Gmail - Inbox").Link("Sign out").ClickBrowser("Gmail: Email from Google").page("Gmail: Email from Google").SyncBrowser("Gmail: Email from Google").Closenext

On executing a test that runs for 2 iterations this is how the test results screen will look like:

I would like to spend some time on examining the code and trying to understand why each line and its order is important for the successful execution of the test:

1. Why am I opening the browser within the ‘for’ loop?2. Why are there sync statements everywhere?3. Why are we programmatically closing the browser at the end instead of letting the

“Record and run settings – Close the browser when test closes” option take care of that for us?

4. Again, why is the close statement inside the ‘for’ loop?

Please note that in the above piece of code, I did not declare the variables in this test, indent the statements or provide comments. This is deliberate as I did not want to dilute the essence of the statements. The following concept will answer these questions:

State of your AUT:The basic rule is – Each iteration should begin with the AUT being the same state and ending in the same state.

If the statement to open the gmail.com page was outside the for loop, the test would run fine for the first iteration but for the next one the gmail.com page would not have been opened and the test would fail.

If the statement to close the browser is not included in the test, then the test would open a browser with each iteration and you would end up with having as many instances of the browser open as the number of rows in the datatable.

Imagine if the close statement was outside the for loop, then also you will end up with too many browsers.

Sync statement: this forces the QTP test to wait until a certain page loads up completely before it starts performing a certain operation on it.

Always try to return your application to the state where it began. This will make sure that you provide the same interface for each of your iteration to interact with.

The following is the piece of code when you are using a local sheet instead of the global:

Browser("Gmail: Email from Google").page("Gmail: Email from

Google").WebEdit("Email").Set DataTable("Name", dtLocalSheet)

Browser("Gmail: Email from Google").page("Gmail: Email from Google").WebEdit("Passwd").SetSecure DataTable("Pwd", dtLocalSheet)

Browser("Gmail: Email from Google").page("Gmail: Email from Google").WebButton("Sign in").Click

In QTP you can parameterize values of:

1. Checkpoints.2. Object properties for a selected step.3. Operation arguments defined for a selected step.4. One or more properties of an object stored in the local object repository in the Object

Properties dialog box or Object Repository window.

QTP Tutorial #18 – Data Driven and Hybrid Frameworks Explained with QTP ExamplesWe are working our way through figuring out how to derive at an automation framework that works best for a certain testing project and also are defining certain frameworks that already exist.

The example that we were using in the previous QTP framework article was creating a new Gmail account.

To start with, we coded the creating of a new account scenario just by recording and play back in a linear fashion. Seeing how it lacked in modularity, readability and reusability we broke it down into functions that would be referenced as keywords moving forward.

We did achieve modularity, readability and reusability through this method but we needed to make the program even more robust so that it can take different sets of values without having to modify the script itself.

That is exactly what we are going to achieve by data driving the tests.

Data Driven automation framework using QTP

Creating multiple Google user accounts is the task we will try to accomplish using this framework.

In the example earlier, we hard coded the first name, last name, user id details etc. into our code while trying to create an account. We will have to separate the code from the data if we have to achieve data driving aspect for this script.

The data should come from a source that is not the program itself.

Typically the data input can be anything:

1. MS Excel files2. Data base3. Text files4. XML files….etc.

Excel files are the ones that get used most often. The very fact that each action in QTP comes integrated with a data sheet of its own explains why that’s so.

You can use one or more data sources for a single script. The excel sheet that comes with the action can be used or you can use an external excel sheet too. Basically a data sheet can be any relevant external file.

For example:This is the code that we need to data drive:

Browser("Gmail: Email from

Google").Page("GoogleAccounts").WebEdit("FirstName").Set "swati"Browser("Gmail: Email from Google").Page("Google

Accounts").WebEdit("LastName").Set "s"Browser("Gmail: Email from Google").Page("Google

Accounts").WebEdit("GmailAddress").Set "test"

All the data right now is hardcoded. Let us now see how we can take these values from the datasheet.

Go to the expert view for the statement in QTP and click on the value column for a step. The following window open up:

Select the parameter option, choose a name for the parameter (this will be the column name in the data sheet) and choose whether you are going to use the global sheet or local sheet (global sheet is available for all the actions in a test, but local sheet is specific to the current action).

For the ‘Name’ field in the screen, QTP provides a default value. The user has an option to keep it the same or change it.

On clicking OK, a new column gets created in the datatable.

This is how the data sheet that contains 3 sets of firstname, last name and account id looks like:

Once parameterized, the code looks like:

123

Browser("Gmail: Email from Google").Page("Google

Accounts").WebEdit("FirstName").Set DataTable("G_First_Name", dtGlobalSheet)Browser("Gmail: Email from Google").Page("Google

Accounts").WebEdit("LastName").Set DataTable("G_Last_Name", dtGlobalSheet)Browser("Gmail: Email from Google").Page("Google

Accounts").WebEdit("GmailAddress").Set DataTable("gmail_address", dtGlobalSheet)

If we have to create these 3 user IDs with the data in the sheets, we need to have 3 iterations. Iteration is nothing but a test run.

Once the data is set up we will have to instruct QTP on how many times this code needs to run, or how many iterations.

This is how we do it: Go to File->Settings and Run  (click on image to enlarge)

In the above screen set the iteration properties as required.

Alternately, you can instruct QTP about the iterations programmatically. As always, this allows more control and also more programming skills. So it is really up to the comfort level of the tester to choose either of these methods.

The components in a data driven framework are:

1. Test script2. Data files3. Shared Functional library(if exists or could be a linear program)4. Object repository (Again, this component will not exist if descriptive programming was used to

create objects)

The test results will show a “Passed’ or ‘Failed’ status for each test run.

Apart from the data table that comes by default, we can use any external excel file as an input sheet.

Hybrid framework

In the example above you used keywords (names of the functions that the user has created) and have data driven the test to make sure that different users are created at the same time. This is nothing but a hybrid framework.

The combination of any two or more frameworks that we have discussed so far is a hybrid framework.

In my experience, no one framework works effectively for a certain project. Hybrid framework is what gets used most often.

Few important points about frameworks:

1. Framework is just a solution that worked best in a certain situation but should not be construed as a set of rules to be definitely followed. It should be seen more like guidelines.

2. There might be many other frameworks in use, we have only listed and explained the common ones

3. Nomenclature – Different people address their frameworks with different names. So if the names are slightly different from one application to another, it is normal.

4. Most of the frameworks can be used in conjunction with one another when any one of them cannot provide an all round solution to your testing goals.

Conclusion:

For the sake of easy understanding we have really simplified the concepts of framework here. If you have any framework related issues that you are facing that is not covered in these articles, do let us know. We will most definitely try to answer your questions. Please feel free to post your questions.