Don’t Assume that Smart Is Always Smart

Smart identification is way by which QTP identifies an object when it is not found in the object repository during the run session. But it is not advisable to use this feature. Because QTP assumes and finds the object during run session, it is not a good idea to assume any think in software testing.

Let us see a simple example how QTP smart identification fails.

Scenario

I want to verify a simple web page which comes, says after I perform some transactions in a website. The web page has a simple text message “Your transaction is successful” after a successful transaction and “Your transaction is not successful” after an unsuccessful transaction. Here you are automating a scenario to check a successful transaction page exists or not after a successful transaction.

The code to check that is

If browser (“Smart is not Smart”).Page (“Smart is not Smart”).WebElement(“Your transaction is successful”).Exist Then

reporter.ReportEvent micPass,”Pass”,”Result Pass”

Else

reporter.ReportEvent micFail,”Fail”,”Result Fail”

End If

This is the sample of that page

sucessful

And the result is

pass

But now consider that the transaction is not successful and you got a message “Your transaction is not successful”

Here is the sample page

unsuccessful

But if you run the above code, the result will be still passing.

pass-warning

What cause this problem? Mr. Smart Identification

The only difference between those web element in successful and unsuccessful transaction is the text. So QTP assumes both the object is same and says pass. Yes, it gives a warning on using smart identification but it is visible only in the QTP result window. If you are using some other external means to document the result, this will never get noticed.

So it is always better to disable smart identification, the simplest way to do is go to File –>Setting–>Run tab and check “Disable Smart Identification during Run Session”

If you want to disable smart identification in you Quicktest Automation Object Model, the script is

Dim App ‘As Application

Set App = CreateObject(“QuickTest.Application”)

App.Test.Settings.Run.DisableSmartIdentification = True

Here is the result after disabling the smart identification.

fail

Advertisements

What Matters Most Is Focus

This is an attempt to write a sequence of articles under “What Matters Most?”

This is to share my experience, how different thinks matters in the field of software testing to bring effective and efficient solutions.

Here is first such an attempt to see how Focus matters.

Of late, I am very addictive to Farmville, a small interesting game in Facebook. Let me brief about this game. This is a simple and fun game where you do farming, add your facebook friends as neighbors, and move up in the game. You can send gifts to your neighbors from the list of available gifts. You need to spend only 5 to 10 minutes a day to make most fun out of this game. It is easy to send same gift to all the neighbors. But as my neighbor list grows, and as each of them wants a different gift it takes longer time to send them the gifts. Suddenly the automation tester within me woke up and said “automate this” (he wakes up very rarely 😉 though). I said wow! That’s a nice idea, let me attempt this and within half an hour, I got a very effective solution. The idea is

1. I need to get the entire request from friends and store it in a single file.

Solution: Oh! There is Google, ask all my friends to update the worksheet in Google Docs, with their wish list

2. Now read this file and start sending their gifts

Solution: Any automation tool can do this by reading the worksheet and schedule this run every day

Now base solution (no no I am not talking chemistry here 🙂 ) is ready, start building on this by adding all the other features like

a. What if gift asked by the neighbor is locked? (The list of gifts gets unlocked one by one as you move up in the game)

b. Send a mail back to neighbor saying that the gift you asked is locked

c. Club similar gift and send them in a single attempt (improve efficiency 🙂 )

This made me to wonder, how did I came up with such a solution so quick? This rarely happens in my projects 😉 . So I started analyzing how I got this solution?

It is “Focus” that made this possible. I just focused on one think need to automate this. I did not think too much on other factors like what tool to use? , Schedule, resources, etc.  Of course, all those are important but focus on them later, to get the solution just focus on one goal at a time (literally goal as in football, can be scored only one at a time 🙂 ). To emphasis more on this, my initial focus on just automating and not concentration on other factors naturally helped me to get other solutions as well.

So, Focus on Mission

Happy Focusing! (I should thank Pari, for adding such greetings at the end of the articles)


General Run Error in QTP

Many times  QTP throws “General Run Error” without any other details.It is always easy to debug if the system throws the appropriate error message.So how to get such error description?

QTP provides a Utility statement called DescribeResult to get the error description.

The syntax is DescribeResult(Error), argument is integer and return value is String

You can get the error number by Err.Number

So to see the description of the error,insert a watch like DescribeResult(Err.Number) in the debug pane or store it in a variable and analyze the error to fix the issue.

There are many such Utility Statement,to uncover more such utility statement go to

QuickTest Professional Help File–>QuickTest Object Model  Reference –> Utility Objects –> Utility Statements

DescribeResult

QTP Tips.txt

There is a Tips.txt present in the QTP installed directory.This has a lot of useful tips.It is present under QTP Installed Directory\dat\Tips.txt.Mostly C:\Program Files\HP\QuickTest Professional\dat

Wondering how did I miss this for so long,there are many interesting and lots of unknown tips(many might be aware of it,at least unknown to me). After uncovering this file, I googled it and found one blog referring to this file. Here is that link, he has given all the tips in the blog.

Count Number of links in a Web Page

In this let us see a script to count number of links in a web page.This will help to understand the descriptive programing better and will help to solve many practical requirements like finding the broken links.

Let us count the number of links in google’s home page

Set mygooglesearch = Description.Create()

Then you declare the property name and value pair for that object,here since we are counting the link,we have to use micclass property  of type link.

mygooglesearch(”micclass”).value =”Link”

Now use childobjects to get the properties into link_count objects,this will give all the child objects of that page of type link.

Set link_count = Browser(“name:=google”).Page(“title:=google”).childobjects(mygooglesearch)

Now we get the object count using count method.

msgbox link_count.count

Simple Parametrization in QTP

Parameterization is used when we need to handle run time data in scripts, consider a scenario of verification of user login to gmail. We verify the user name displayed at the top right corner to make sure that the user logged is correct. But the name displayed depends on the login id used and is not static, so we need to parameterize the value.
Parameterization may be done by passing values as variable or through data sheet. It is always a good practice to user data sheet, so that editing the data during play back and maintenance will be easier.
Below is the sample code for parameterization through variables
Id = “<emailid@gmail.com>”
Pwd= “<password>”
Browser(“Google”).Page(“Google”).Link(“Sign in”).Click
Browser(“Google”).Page(“Google Accounts”).WebEdit(“Email”).Set(Id)
Browser(“Google”).Page(“Google Accounts”).WebEdit(“Passwd”).SetSecure(Pwd)
Browser(“Google”).Page(“Google Accounts”).WebButton(“Sign in”).Click
‘ Verification point verifies whether used has successfully logged in by checking the email displayed after logging in
Login = Browser(“Google”).Page(“iGoogle”).WebElement(“innertext:=”&Id).GetTOProperty(“innertext”)
msgbox(Login)
If Login=Id Then
Browser(“Google”).Page(“Google”).Link(“iGoogle”).Click
Browser(“Google”).Page(“iGoogle”).Link(“innertext:=Sign Out”).Click
Else
msgbox(“Login Failed”)
End If
Below is the sample code for parameterization through datasheet
Browser(“Google”).Page(“Google”).Link(“Sign in”).Click
Browser(“Google”).Page(“Google Accounts”).WebEdit(“Email”).Set(DataTable(“EmailID”, dtGlobalSheet))
Browser(“Google”).Page(“Google Accounts”).WebEdit(“Passwd”).SetSecure(DataTable(“Password”, dtGlobalSheet))
Browser(“Google”).Page(“Google Accounts”).WebButton(“Sign in”).Click
‘ Verification point verifies whether used has successfully logged in by checking the email displayed after logging in
Login = Browser(“Google”).Page(“iGoogle”).WebElement(“innertext:=”&DataTable(“EmailID “, dtGlobalSheet)).GetROProperty(“innertext”)
msgbox(DataTable(“EmailID”, dtGlobalSheet))
If Login=DataTable(“EmailID”, dtGlobalSheet) Then
Browser(“Google”).Page(“Google”).Link(“iGoogle”).Click
Browser(“Google”).Page(“iGoogle”).Link(“innertext:=Sign Out”).Click
Else
Message = Browser(“Google”).Page(“Google Accounts”).Webelement(“html id:=errormsg_0_Passwd”).GetROProperty(“innertext”)
msgbox(Message)
If Message = “Username and password do not match” Then
msgbox(“Login Failed”)
Else
msgbox(“Invalid Error message”)
End If
End If

Parameterization is used when we need to handle run time data in scripts, consider a scenario of verification of user login to gmail. We verify the user name displayed at the top right corner to make sure that the user logged is correct. But the name displayed depends on the login id used and is not static, so we need to parameterize the value.

Parameterization may be done by passing values as variable or through data sheet. It is always a good practice to user data sheet, so that editing the data during play back and maintenance will be easier.

Below is the sample code for parameterization through variables

Id = “<emailid@gmail.com>”

Pwd= “<password>”

Browser(“Google”).Page(“Google”).Link(“Sign in”).Click

Browser(“Google”).Page(“Google Accounts”).WebEdit(“Email”).Set(Id)

Browser(“Google”).Page(“Google Accounts”).WebEdit(“Passwd”).SetSecure(Pwd)

Browser(“Google”).Page(“Google Accounts”).WebButton(“Sign in”).Click

‘ Verification point verifies whether used has successfully logged in by checking the email displayed after logging in

Login = Browser(“Google”).Page(“iGoogle”).WebElement(“innertext:=”&Id).GetTOProperty(“innertext”)

msgbox(Login)

If Login=Id Then

Browser(“Google”).Page(“Google”).Link(“iGoogle”).Click

Browser(“Google”).Page(“iGoogle”).Link(“innertext:=Sign Out”).Click

Else

msgbox(“Login Failed”)

End If

Below is the sample code for parameterization through datasheet

Browser(“Google”).Page(“Google”).Link(“Sign in”).Click

Browser(“Google”).Page(“Google Accounts”).WebEdit(“Email”).Set(DataTable(“EmailID”, dtGlobalSheet))

Browser(“Google”).Page(“Google Accounts”).WebEdit(“Passwd”).SetSecure(DataTable(“Password”, dtGlobalSheet))

Browser(“Google”).Page(“Google Accounts”).WebButton(“Sign in”).Click

‘ Verification point verifies whether used has successfully logged in by checking the email displayed after logging in

Login = Browser(“Google”).Page(“iGoogle”).WebElement(“innertext:=”&DataTable(“EmailID “, dtGlobalSheet)).GetROProperty(“innertext”)

msgbox(DataTable(“EmailID”, dtGlobalSheet))

If Login=DataTable(“EmailID”, dtGlobalSheet) Then

Browser(“Google”).Page(“Google”).Link(“iGoogle”).Click

Browser(“Google”).Page(“iGoogle”).Link(“innertext:=Sign Out”).Click

Else

Message = Browser(“Google”).Page(“Google Accounts”).Webelement(“html id:=errormsg_0_Passwd”).GetROProperty(“innertext”)

msgbox(Message)

If Message = “Username and password do not match” Then

msgbox(“Login Failed”)

Else

msgbox(“Invalid Error message”)

End If

End If

Connecting to DB through QTP

Methods Used: ADO Connection object

What is ADO connection?

Microsoft’s ActiveX Data Objects (ADO) is a set of Component Object Model (COM) objects for accessing data sources. It provides a layer between programming languages and OLE DB (a means of accessing data stores, whether they be databases or otherwise, in a uniform manner). ADO allows a developer to write programs that access data without knowing how the database is implemented. You must be aware of your database for connection only. No knowledge of SQL is required to access a database when using ADO, although one can use ADO to execute arbitrary SQL commands. The disadvantage of this (i.e. using SQL directly) is that it introduces a dependency upon the type of database used.

To learn more about ADO visit http://www.w3schools.com/ADO/ado_ref_connection.asp

Let us look how to connect to database(DB) in QTP, the steps involved are

  1. Create an object of type ADODB.Connection.
  2. Using the connection string establish a connection to the DB.
  3. Execute the query and store the query result to Recordset collection.

Let us see code snippet how to connect to the flights MS Access DB

STEP 1:

Set connect = CreateObject (“ADODB.Connection”)

STEP 2:

This can be done by many ways, if there is a system DSN created then you can use that directly to establish a connection.

connect.open “QT_Flight32” ‘here this is the QT_Flight32 is the system DSN name.

if there is no system DSN, then you can give the DB details directly as

Connect.open “Driver={Microsoft ODBC for Oracle}:Server=DBserver,UID=Sa,Password=sa”

Here you have to give the Driver type like oracle,sybase then server name, user id and password.

STEP 3 :

Set RS = connect.execute(“select flight_number from flights where flight_number = 2004” )

Now the RS object has the query result ,using loop we can get those data.

Count1 = RS.fields.count

Do

For  i = 0 To count1-1

MsgBox(RS.fields(i).name)

MsgBox(RS.fields(i).value)

Next

RS.MoveNext

Loop until RS.EOF