Wednesday, February 1, 2012

Using Classes in QTP/VBScript

Using Classes in QTP

QTP works on VBscript which is a scripting language not a programming language but it still supports “Class” concept in a limited manner. It does not support inheritance (which I believe is a major drawback) but you can leverage encapsulation and beautify your code.
Reasons to use Classes in QTP/VBscript:
1.       Achieve Encapsulation
2.       Create logical structure/packaging of functions
3.       Make code more readable
4.       Passing variables make easy

Achieve Encapsulation:

Some time we end up creating some variables global variables which can be accessed through multiple functions. Creating a Public Variable at function library level means that it can be modified by any of the function, even to those functions which should be modifying it. You can restrict it by creating it Private at class level.

Logical Structure/packaging and better readability:

Say example, I have a bunch of functions which does reporting, lying in function library. We log at different places like adding a node at XML , marking a row pass in Excel , adding a step at QC and saving screen print in Word. So my function library looks like this:

‘Reporting functions
‘-----------------------XML functions starts ----------------------------------------------------
Sub CreateXML(FilePath)
End Sub

Sub AddNodeToXML(NodeName,NodeText,ParentXPath)
End Sub

Sub SaveXML(FilePath)
End Sub
‘-----------------------XML functions ends----------------------------------------------------
‘-----------------------Excel functions starts ----------------------------------------------------
Sub CreateExcel(FilePath)
End Sub

Sub MarkTestCasePassInExcel(TestCaseName)
End Sub

Sub SaveExcel(FilePath)
End Sub
‘-----------------------Excel functions starts ----------------------------------------------------
‘-----------------------QC functions starts ----------------------------------------------------
Sub AddStepToQC(StepStatus, StepName, StepDescription,StepExpected,StepAtual)
End Sub

Sub DeleteStepFromQC(StepID)
End Sub
‘-----------------------QC functions Ends----------------------------------------------------
‘-----------------------Word functions starts ----------------------------------------------------
Sub CreateWord(FilePath)
End Sub

Sub AddTextToTestProof(Text)
End Sub

Sub SaveScreenShotToTestProof()
End Sub

Sub SaveTestProof(FilePath)
End Sub
‘-----------------------Word functions Ends ----------------------------------------------------

Lets “Class-ify” it

‘Reporting functions
‘-----------------------XML Class starts ----------------------------------------------------
Class XMLReporting
                Sub Create(FilePath)
                End Sub

                Sub AddNode(NodeName,NodeText,ParentXPath)
                End Sub

                Sub Save(FilePath)
                End Sub
End Class
‘-----------------------XML Class ends----------------------------------------------------
‘-----------------------Excel Class starts ----------------------------------------------------
Class XLReporting
                Sub Create(FilePath)
                End Sub

                Sub MarkTestCasePass(TestCaseName)
                End Sub

                Sub Save(FilePath)
                End Sub
End Class
‘-----------------------Excel Class starts ----------------------------------------------------
‘-----------------------QC Class starts ----------------------------------------------------
Class QCFunctions
                Sub AddStep(StepStatus, StepName, StepDescription,StepExpected,StepAtual)
                End Sub

                Sub DeleteStep(StepID)
                End Sub
End Class
‘-----------------------QC Class Ends----------------------------------------------------
‘-----------------------Word Class starts ----------------------------------------------------
Class TestProof
                Sub Create(FilePath)
                End Sub

                Sub AddText(Text)
                End Sub

                Sub SaveScreenShot()
                End Sub

                Sub Save(FilePath)
                End Sub
End Class
‘-----------------------Word Class Ends ----------------------------------------------------

This Code looks more structured then the previous one and is more readable
Function Calls will Look Like This
Set XML = New XMLReporting
XML.Create “C:\Temp.xml”
XML.AddNode “Step”, “Loan Booked”, “.//”

The one I have implemented in my project looks like this
‘Previous Call
QCUploadAttachmentToCurrentTestInstance “C:\Temp.xml”
QCDownloadAttachmentFromTestPlanFolder  “Subject\TestFolder\TestData.xls”

‘Now it looks like
QC.Upload.ToCurentTest “C:\Temp.xml”
QC.Download.FromTestPlan “Subject\TestFolder\TestData.xls”

Data Passing:

If you wanted to pass a new argument to a function which is called from multiple places, then you have to do a lot of rework changing every call of that function. However in order to deal with this we use work around like
a.       Making some variable Public so that it can be used inside function
b.      Passing multiple comma separated values in a single argument
c.       Passing an array
d.      Passing dictionary object

Another workaround can be passing Custom defined data structure.
Let’s consider that you are testing mortgage calculator functionality. Calculator takes some details of applicant and displays eligibility criteria of Mortgage loan. You are replicating calculation logic in your automation script in order to validate the eligibility criteria displayed on application.

‘Code Snippet 1
ApplicantName = "John"
ApplicantAge = 30
ApplicantIncome = 100  'Poor Chap
ApplicantAddress = "CyberWorld"

Eligiblity = CalculateEligibilityCriteria(ApplicantName, ApplicantAge, ApplicantIncome, ApplicantAddress)

Function CalculateEligibilityCriteria (Name, Age, AnualIncome, Address)
                'Calculate Eligibilty and Return Value
End Function

‘Code Snippet 2
Class ApplicantDetails
                Public Name
                Public Age
                Public AnualIncome
                Public Address
End Class


Set Applicant = New ApplicantDetails

Applicant.Name = "John"
Applicant.Age = 30
Applicant.Income = 100 'Poor Chap
Applicant.Address = "CyberWorld"

Eligiblity = CalculateEligibilityCriteria(Applicant)

Function CalculateEligibilityCriteria (objApplicant)
                'Calculate Eligibility and Return Value
End Function

Using Class to pass custom data structure makes it more readable and more flexible to accommodate changes