The online community for software testing & quality assurance professionals
 
 
Calendar   Today's Topics
Sponsors:
Lost Password?

Home
BetaSoft
Blogs
Jobs
Training
News
Links
Downloads



Testing Tools >> HP/Mercury QuickTest Pro

Pages: 1 | 2 | 3 | >> (show all)
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
vbScript FAQ and Useful Resources
      #348942 - 12/21/06 05:37 PM

Overview

This thread is started for the purpose of sharing information I have picked up over the last 2 months as I have tried to learn how to use the vbScripts language. I feel that learning vbScript fundamentals is an essential part of learning to work effectively with QTP.

While my journey is by no means over, I wanted to get this information out there, so other new folks can get started as efficiently as possible.

I encourage others on this forum to provide other resources and FAQs—or to argue a counterpoint to those I provide in follow-on replies to this thread starter.

But please do not post raves, rants and other forms of content-free replies to this thread. These just clutter up the thread and make it difficult for others to find the real information.

-Hope this helps, Terry Horwath

------------------------------------

The Basics

In no particular order:

1. The Microsoft vbScript Version 5.6 Documentation, provided in a standard online HELP file *.chm format, should be considered your basic gold standard reference. Once you get past your basic learning curve this is often the only reference you will need. QTP bundles a version of this file, but if you need or want to get a copy from the mothership here is the URL to download a copy:

http://www.microsoft.com/downloads/detai...;displaylang=en

Note that the above online documentation unfortunately mixes Microsoft’s support for both vbScript and javaScript, so be aware of this as you prowl through this guide (applicability is noted at the top of each section).

2. While the above document is great for looking up a particular Property, feature, Function, Method, etc., it is not the best way for most of us to learn language basics, and more importantly, to see how the various components and constructs are related. To address this aspect I can personally recommend the O’Reily “vbScript in a Nutshell” manual, but that book costs about $30. An online, free, resource that is almost as good can be found at yet another Microsoft URL; then follow the “vbScript” link on the page:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/Scriptinga.asp

3. vbScript is designed to, and requires, a compliant runtime environment, also referred to as a host. The Microsoft documentation assumes that you are going to write for and run scripts in the Windows Script Host (WSH) environment and to often use the language to control Windows Management Instrumentation (WMI) objects, or to write active server web pages. But what we are interested in is Mercury’s QTP runtime environment support for vbScript. Keep this in mind when using the MS documentation (including that provided by QTP), because you will occasionally find that not all features and functions described in the MS documentation is supported in the QTP runtime. For example QTP does not provide the root wscript object described in the MS documentation. (This issue will, or at least should, be addressed by subsequent additions to this thread).

Beyond the Basics

In no particular order:

1. A forum dedicated to all things vbScript, very similar to sqaforums.com is www.visualbasicscript.com Like this forum you need to set up an account to ask questions. The moderators are very knowledgeable (and appear to answer most of the posts). But be aware—this forum expects that you will search before posting, and will have taken modest steps to find your answer with web searches.

2. A great resource to get scripting ideas, possible solutions to your problem, and to find vbScript syntax dissected with commentary is, once again, a Microsoft site dedicated to promoting vbScript usage. It is called the Hey Scripting Guy! forum and can be found at the following URL:

http://www.microsoft.com/technet/scriptcenter/resources/qanda/default.mspx

While the focus is primarily WMI, they post 5 articles a week, and the archive goes back about 2 years. It contains a wealth of information about using vbScript techniques and objects.

3. If you are going to develop two or more shared libraries for inclusion with your QTP test cases, learn how to encapsulate each library in a vbScript Class. Once vbScript basics are mastered, learning to develop Classes and instantiate objects is a small additional effort. The primary advantages to using classes are the ability to (a) hide Private data variables, (b) control access to Public variables through the use of Properties and (c) maintain logical and separate namespaces in each library--for example object "fileio" and "msglog" can each have a Write() method: fileio.Write() and msgLog.Write().


Other vbScript Basics Related Articles

In no particular order, other articles I have recently posted that address vbScript basics:

1. Use of the special characters for line continuation and multiple statements per line:

http://www.sqaforums.com/showflat.php?Cat=&Board=UBB20&Number=344186

2. The wscript Object and QTP:

http://www.sqaforums.com/showflat.php?Cat=&Board=UBB20&Number=347101

3. wscript.Sleep throws and exception:

http://www.sqaforums.com/showflat.php?Cat=&Board=UBB20&Number=347071

4. I and others have also posted what we feel are useful shared code examples in the following thread:

http://www.sqaforums.com/showflat.php?Cat=0&Number=347046

------------------------------------------

Search words/phrases to find this thread: newby; new user; vbScript basics; vbScript FAQs; vbScript Resources; vbScript Help; getting started


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #349110 - 12/23/06 09:30 AM

Article Title: Misleading error message using ExecuteFile()

Sigh, sometimes QTP can be so frustrating...

In the following code example, the file xx.vbs does not exist:
Code:

'my test case
'
msgBox "what a misleading error message:"
'
ExecuteFile "xx.vbs"


The Run Error dialog presented by QTP (I am using version 8.2) when it executes this code is:

Invalid procedure call or Argument

Details>> Line (1) "'my test case".

Totally misleading. But now you know to watch for this.

-Terry


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #349120 - 12/23/06 06:46 PM

Article: Subs, Functions, and those pesky parens: ()

You execute the following code:

Code:

function x(s) 'by default, s is passed "byRef"
s="altered by x()"
end function
'
sVar="zero"
'
x(sVar)
msgBox sVar
'
call x(sVar)
msgBox sVar


The first time function x() is invoked, using the "x(sVar)" form,
sVar is not modified after x() returns.

But the second time function x() is invoked, using the "call x(sVar)"
form, sVar is modified, as expected, after x() returns.

So what the heck is going on here?

Well the following post probably describes more than you will
ever want to know about this subject:

http://www.visualbasicscript.com/m_41080/tm.htm

But getting a good handle on when to use ()'s, and why is important to
using vbScript successfully (and avoiding alot of subtle
problems--this is nuanced language).

-Terry


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #349669 - 12/28/06 06:49 AM

Article: Assignment and Evaluation nuances

Based on my understand of C and Java, the following code snippet should assign the return value of foo() to iNum, and then compare iNum to False:

Code:

Function foo ()
foo=7
End Function
'
'
If (iNum=foo())=False Then
'
If isEmpty(iNum) Then
msgBox "Eval1, iNum is not initialized"
else
msgBox "Eval1, iNum returned FALSE"
End If
else
msgBox "Eval1, iNum: " & iNum
End If
msgBox "after Eval1, iNum: " & iNum


Based on this [erroneous] assumption we would expect to see two message boxes, each indicating that iNum has a value of 7. Well, in vbScript the results are: the first message box indicates that iNum is ...not initialized and the 2nd displays nothing for the value of iNum--both because iNum is still equal to Empty.

What I believe the above IF statement is saying is (1) "is iNum (which has a value of Empty) equal to 7? (the value returned from foo), the answer of which is False, and then (2) is False equal to False?, the answer of which is True, so the IF THEN statements are executed.

You then review the MS online vbScript doc and see that there is a well written section that describes the Eval and Execute functions that are designed to deal with the overloading of the '=' equals sign. So then you might conclude that the following code would now allow us to assign iNum and evaluate its value, all in a single statement:

Code:

If Execute("iNum=foo()")=False Then
'
If isEmpty(iNum) Then
msgBox "Eval2, iNum is not initialized"
else
msgBox "Eval2, iNum returned FALSE"
End If
End If
msgBox "after Eval2, iNum: " & iNum


Well, the results are still not what we want or expect, because the Execute() function is not returning the value assigned to iNum--although now, at least iNum is being initialized with the return value from foo().

The bottom line is, you need to discipline yourself to perform the assignment and then an evaluation of that assignment in two statements, to ensure correct functionality, as in:

Code:

iNum=foo()
If iNum=False Then


All code in this article was executed/validated in both the WSH and QTP runtime environments. I encourage replies to this post if you have syntax--that you have validated in both environments--that achieves assignment and evaluation in a single statement.

-fyi, Terry Horwath


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #349919 - 12/29/06 08:07 PM

Article: exploiting vbScript's variant return data type

For those of us used to working with strongly typed languages (like C, Java, C++, etc) working with vbScript's single variant data type (where any variable can hold any type of data, and morph over time) can take some getting used to.

But beyond the "a novice can get some code to work really fast without much knowledge" argument (hum...), I have recently realized that vbScript, unlike strongly typed langs, provides multi-state function return possibilities. For example in the following code snippet:

Code:

Option Explicit
'
function foo(iRetControl)
'
if iRetControl=1 then
foo="abc"
else
foo=False
end if
end function
'
dim s
'
s=foo(1)
if s=False then
msgBox "foo(1) returned boolean False"
else
msgBox "foo(1) returned string: " & s
end if
'
s=foo(2)
if s=False then
msgBox "foo(2) returned boolean False"
else
msgBox "foo(2) returned string: " & s
end if


foo() can return a String or a Boolean False. And the code that evaluates these return values does not have to do any casting.

This, at least for me, has significant advantages when writing functions that return say a string, integer, array, whatever when they execute successfully and a boolean False (or whatever) when they encounter some type of failure.

If you have not spotted this nuance, now you have another tool in your toolbag.

-fyi, Terry Horwath


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #349961 - 12/31/06 10:34 AM

re: exploiting vbScript's variant return data type

This follow-on post provides a more concrete example, and shows how this capability can be turned around, in that it may be more appropriate to return say a True value when a function executes as expected, with a variety of returns based on failure. For example:
Code:

function WriteFile (sFilespec, sBuffer)
'
if sBuffer is successfully written to sFilespec then
WriteFile=True
else
WriteFile="description of failure"
end if
end function
'
'
retCode=WriteFile("c:\a\b\myfile.txt", "blah, blah")
if NOT retCode then
use the returned string to process/log the error...
ExitTest
end if
continue on with the test...


With a slightly more complex example and called function your test code's response can be conditioned by a passed return control variable. For example:
Code:

function WriteFile (sFilespec, sBuffer, bLogError)
'
if sBuffer is successfully written to sFilespec then
WriteFile=True
else
if bLogError then
Reporter.ReportEvent ...
WriteFile=False
else
WriteFile="description of failure"
end if
end if
end function
'
'
retCode=WriteFile("c:\a\b\myfile.txt", "blah, blah", True)
if retCode=False then
'error was logged by WriteFile(), exit test now
ExitTest
end if
continue on with the test...


In the 2nd code example you can choose to process the error yourself (last parm set to False), or to let WriteFile() log the error (last parm set to True) and simply return the calling code a False when a failure is encountered.

-fyi, Terry


Post Extras: Print Post   Remind Me!   Notify Moderator  
seminole
Junior Member


Reged: 05/18/06
Posts: 66
Re: vbScript FAQ and Useful Resources *DELETED* [Re: thorwath]
      #351756 - 01/10/07 05:03 AM

Post deleted by Terry Horwath

Post Extras: Print Post   Remind Me!   Notify Moderator  
RKY
stranger


Reged: 08/22/06
Posts: 586
Loc: Bangalore, India
Re: vbScript FAQ and Useful Resources [Re: seminole]
      #354744 - 01/24/07 04:59 AM

For more info on VB script along with example by section by section
Look into this below ulr

http://www.html.dk/dokumentation/vbscript/
html-vss/vbstoc.htm

I hope this make sense

Regards,
Ram.

--------------------

Hope this helps you,


- RKY


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #360048 - 02/16/07 10:21 AM

Subject: include() method

Below is a simple chunk of code I have seen on a few sites (and in a few books) that provides a generic method for "including" any number of vbScript files in a program running in a non-QTP environment (such as WSH).
Code:
  
'*************************************************************************
'
' Implements a simulated "include" capability in a vbScript,
' using ExecuteGlobal to ensure the "included" file's contents are
' available to all.
'
' from the public domain Old Dominion University website, at
' http://www.cs.odu.edu/~wild/cs477/Spring01/Examples/Script/wrox/Chapter05
'
' *************************************************************************
'
Option Explicit
'
'
' Include() vbScript sub implements a generic "include" capability
' to your scripting library environment.
'
Sub include(file)
'
Dim fso, f, str
'
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(file, 1)
str = f.ReadAll
f.Close

ExecuteGlobal str
End Sub
'
'
' Once the above sub is part of your main global library, you
' can then include any number of additional libs using the
' following statement.
'
include "anotherVbScriptLib.vbs"



Keep in mind that this function is not recommended for use in QTP--in that runtime environment either use QTP's ExecuteFile() function or add the files to include on the Resource tab in the Test Options workflow.

-Terry Horwath

P.S. Here is an unbroken link to the interesting site recommended in the above posting:

http://www.html.dk/dokumentation/vbscript/html-vss/vbstoc.htm


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #362578 - 02/27/07 11:56 AM Attachment (395 downloads)

Subject: Working with a custom vbScript Class

This post is intended for those who have wanted to investigate writing and using custom vbScript classes to supplement their QTP scripting, or perhaps more realistically, their vbScript library development.

I am not claiming to be a vbScript expert when it comes to custom classes. Rather I wish to share the information I have learned over the last several months, information I wish I could have read about in one concise thread like this when I was getting started.

-Terry Horwath


Executing the Example

Attached to this posting is a file, classExample.txt. Save this file to your disk as classExample.vbs. While this example will run, all of the good bullet proofing for error checking have been stripped—out, so that the basic elements of a custom vbScript class can more easily explored.

As currently commented, this class code only executes under the Windows Scripting Host (WSH) runtime environment on your PC. Should you care to run it under QTP--which offers no real advantage for learning purposes--you will need to make some comment changes within the sleep() method in the class definition.

After saving the attachment as described above, double-click on the file. The code at the bottom of the file is intended to allow you to interact with the custom class, myClass, and its instantiated object, myObj. When executed you should see:

1. A small IE window is displayed.
2. A msgBox with some info about the window is displayed.
3. Thereafter following the msgBox instructions to conclusion.

Now, before diving into the full source code for this class, take the time to read the following sections which attempt to grow the example from the ground up.


vbScript Class Overview

When you see a programming language that supports “class” and “object” you tend to (or at least I tend to) think of a traditional object oriented programming (OOP) environment that supports the following general characteristics:

http://en.wikipedia.org/wiki/Object-oriented_programming


But vbScript’s support for “class” and “object” is more modest in scope:

http://www.microsoft.com/mind/1199/classes/classes.asp


To summarize, the vbScript class concept:

1. Does NOT support inheritance. So it is not possible to create a Collie class which inherits characteristics from a Dog class which inherits characteristics from a Mammal class, etc.

2. Does NOT support polymorphism. Kind of a related to inheritance, where for example a Dog class will “bark” and a Pig class will “oink” when they are asked to “speak” (in a class hierarchy where they inherited the base Speak() method from the Mammal class, then override that method to implement animal unique behavior).

3. DOES support encapsulation, an OO technique which conceals how a particular class is implemented, independent from objects that use the class’s Public Properties and Methods. Another way to think about encapsulation is to say it is the ability to hide implementation details while sharing higher level behavior.

It is this author’s opinion that the lack of inheritance and polymorphism are not major shortcomings in scripting environments such as WSH and especially QTP, where you are not trying to build large complex OO programs.

Encapsulation is then the primary reason to consider using vbScript classes. And, with encapsulation comes namespace control--which permits any number of class elements to be named foo as long as each of those elements resides in a different class (i.e. a different namespace).


vbScript Class Basics

Here is the basic syntax and keywords for the vbScript Class statement:

http://www.html.dk/dokumentation/vbscript/HTML/vsstmClass.htm

Using this syntax, lets start building a new custom class:
Code:

class myClass

end class



The above class is of course useless, but none-the-less fully formed. You instantiate (fancy word for create) an object from this class using the following syntax:
Code:

dim myObj
set myObj = new myClass



Now we have a useless but fully formed object.


A Bit Less Useless Class

Now lets start adding some meat to the class. The first capabilities we explore are the built-in, but optional, methods:

Class_Initialize()
http://www.html.dk/dokumentation/vbscript/HTML/vsevtinitialize.htm

Class_Terminate()
http://www.html.dk/dokumentation/vbscript/HTML/vsevtterminate.htm

Code:

class myClass
Private sub Class_Initialize()
MsgBox("myObj has been created")
End sub

Private sub Class_Terminate()
MsgBox("myObj has been terminated/destroyed")
End Sub
end class

dim myObj
set myObj= new myClass ‘implicitly execute Class_Initialize()
myObj = Nothing ‘implicitly execute Class_Terminate()



Still pretty useless, but the above class and its instantiated object can be executed interactively in the WSH environment should you care to experiment.

The idea here is to place all your object initialization code statements in Class_Initialize() and all your tear-down code, such as closing windows, sessions, etc. in Class_Terminate().

Note: my evaluation of QTP’s (version 8.2) support for custom classes shows me its runtime fails to call the Class_Terminate() method when an object is implicitly destroyed when a test terminates prior to explicitly destroying the object. I consider this a bug.


Working with Class Properties

A Property is a named data variable of a class. Properties define object characteristics such as size, color, and screen location, or the state of an object, such as enabled or disabled.

At this point we add one Public and one Private Property, and the Private Property’s associated Get() and Let() methods to our class:
Code:

class myClass
Public iVar
,
Private iWidth
'
Public Property Let Width(iPixels)
iWidth=iPixels
End Property
'
Public Property Get Width()
Width=iWidth
End Property
end class
dim myObj
set myObj= new myClass



In the above example we are using the Private and Public keywords, which while not unique to the Class statement, offer enforcement of “visibility” external to the Class. Public Class properties are visible within the Class block, as well as by code outside the Class block, but Private Class properties are visible only within the Class block.

Class Properties provide more complex support for control and access over data variables, but their syntax is similar to working with global variables:
Code:

myObj.Width= 1234 ‘write (Private) iWidth indirectly through its Let method
myWidth = myObj.Width ‘read (Private) iWidth indirectly through its Get method

myObj.iVar = 1234 ‘write (Public) iVar directly
myVar = myObj.iVar ‘read (Public) iVar directly

myObj.iWidth=1234 ‘ERROR, (Private) iWidth is hidden from the caller
myWidth =myObj.iWidth ‘ERROR, ditto…



First lets discuss the Public iVar class Property. It is nothing more than a glorified global variable, and its only advantage over a global variable is namespace control (i.e. in other words we could have an iVar in multiple classes without a naming collision).

Now for the much more interesting Private iWidth Property. Why have we gone to all this trouble to read and write the iWidth variable, indirectly through its associated Get and Set methods? The short answer is data encapsulation—-the iWidth variable can’t be accessed external to the class without using its Get and Let methods, but it still looks like a typical data variable to the outside world. The longer answer is hopefully explained with the extended example below, which shows error handling and bullet proofing code added to the Width Let Property:
Code:

Public Property Let Width(iPixels)

if NOT isNumeric(iPixels) Then
Exit Property
End If
if iPixels<250 Then '250 min pixel width enforced by the IE Object
iWidth=250
elseif iPixels > gLib.getScreenWidth/2 Then
iWidth=gLib.getScreenWidth/2
else
iWidth=iPixels
end if
End Property



You could of course write a class method, or a global non-class function, to achieve the equivalent bullet proofing, but this use of class Get/Let Properties adds extensible error checking and data range enforcement to a seemingly simple data assignment statement.

There is another advantage to using class Get/Let Properties as well: unlike a global variable that can be altered from anywhere in your global code, the only way to write the iWidth variable in our custom object is through its Let Width() method. This provides a centralized means to determine (and when debugging, trap) when the value is modified and by who.

Note that within the class itself the Private iWidth variable can be accessed directly. This is because class code is always considered trusted. Note also that you can have a Let method without an associated Get method and visa-versa, depending on your needs.


Working with Class Methods

A class Method is nothing more than a vbScript Function or Subroutine encapsulated within a Class code block. Here again we can use the Private and Public keywords to control visibility outside of the class:
Code:

class myClass
Public function foo (parm1, parm2)
do some work…
bar()
foo=someReturnValue
end function
'
Private sub bar ()
do some work internal to this class…
end sub
end class



In the above example the foo() method can be called from outside the class, but not the bar() subroutine. The bar() subroutine is meant to do class internal implementation work and therefore it is intentionally hidden from the world outside of the class. Here again we have another example of encapsulation in action.


Putting It All Together – Exploring the Attached Example in Detail

All of the keywords and concepts associated with a custom vbScript class have now been introduced and explained. Returning to the attached example, we will step through each line of code at the bottom of the file; which is the code intended to execute and use the custom class:

line #178 set myObj = new myClass
A new object is created from the custom class. Anywhere from a little to a lot of work gets performed in this single statement, because the Class_Initialize() method is implicitly called.

line #188 myObj.Height = 400
line #189 myObj.Width = 200
These two lines of code explicitly set the height and width of the IE window we are about to spawn. Both of these statements are optional, and override the default window size established by the Class_Initialize() method.

line #191 myObj.Open(True)
This line of code calls the required Open() class method, which does the heavy lifting to create and then invoke an IE window. This line of code demonstrates the power of encapsulation because not only is a lot of functionality implemented in this method, but the method also initializes the hidden IE object, ieObj, on line #25 used to maintain and interact with the spawned IE window (in this manner the foreground code works with the myObj object, while the class itself works with the much more complicated “Internet.Explorer” object). The Boolean value passed to this method determines if new lines of text written to window will be pre- or post-appending in the window. (It is counter-intuitive that you most often want to pre-append new lines to this type of “watch” window, so that the newest lines are always visible).

line #195 myObj.write("one" & vbCR)
line #199 myObj.write("two" & vbCR)
Well, these lines simply demonstrate writing to the just created IE Window. In real usage this would occur for the life of a test case, from any number of Actions (that have access to the myObj object), again and again, as the test progresses through its paces, occasionally writing status/progress messages to the window.

line #203 myObj.Close
The myObj object is destroyed, which internally destroys the “Internet.Explorer” object and the IE window is deleted from the PC desktop.


Digging Deeper – The Full ieWindow Class

If you haven’t had enough yet…

The attached example is a stripped-down version of my full ieWindow class, which is available on this forum—-with a terse document—-in the following post:

http://www.sqaforums.com/showthreaded.php?Cat=0&Number=348572&page=0&vc=1

Substantially more functionality and bullet-proofing is contained in this real class--in particular--code to gracefully deal with a user interactively closing the IE window.

Note that unlike the attached example, the above full ieWindow class only executes in the QTP runtime environment.


Post Extras: Print Post   Remind Me!   Notify Moderator  
EAS
Advanced Member


Reged: 01/22/02
Posts: 684
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #362679 - 02/27/07 09:31 PM

Terry, That's good stuff.

You could also add the use of the "Default" key word to the procedure name to enable a default method that can be used without specifying the name. By using something like:

Code:

Public Default Function Bar(strName)



You can call it from your Foo object like:

Code:

strXXX = Foo.Bar("Terry")


or
Code:

strXXX = Foo("Terry")



Also, instead of creating your object in your library file you can do it in your script if you add a small helper function to your library.

Code:

Function GetClass()
Set GetClass = New myClass
End Function



Now in your actions you can do this:

Code:

Dim objFoo
Set objFoo = GetClass



This allows you to create objects with a scope other than global. It also allows you to create as many objects as you want.

I generally use classes to wrap some object or to create libraries of utility methods. I frequently wrap dictionary objects in classes to store data and access it in ways that are filtered and manipulated through methods and properties.

Using classes can help build easy to use "frameworks" by organizing things into objects.

--------------------
TDForums.com


Edited by Tarun Lalwani (02/28/07 11:39 AM)


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: EAS]
      #362812 - 02/28/07 06:33 AM

EAS,

Thanks for these comments and pointers.

The use of vbScript classes and their instantiated objects are very flexible. It was not my intention to indicate that they could only be used in the same manner as I presented them in my "introduction to vbScript classes" posting.

In particular, I did instantiate the object right after the class def in my example, thus making it a global object. I used this technique (which I really should not have done in an "introduction to..." type of post) because I am currently using classes to encapsulate my shared libs, each in their own class--using this technique it made sense to create one global object per library, to allow all QTP actions to reference each lib (and, more importantly for one lib to call another lib's "well known" object).

Thanks again for making these observations.

-Terry

P.S. Hey EAS, any chance you could edit your above post? I believe the last Code block is not terminated correctly, and
is now forcing the entire thread to display about 15" wide.

Edited by Terry Horwath (02/28/07 06:36 AM)


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #363204 - 03/01/07 08:12 AM

Subject: Calling a test case function from a Library Function

The following thread points out some rather unexpected behavior if you try to call a test case function from a function that is part of a vbScript library included by the test case. While this is a bit of a brain twister, and why you would want to do this is not readily apparent, you want to remember that this scenario is not supported by at least version 8.2 of QTP:

http://www.sqaforums.com/showflat.php?Cat=0&Number=362982&an=0&page=0#Post362982


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #363206 - 03/01/07 08:20 AM

Subject: Working with the Dictionary Object

Code:

Option Explicit
'
Dim strKey, myObj, myObj2
'
Set myObj = CreateObject("Scripting.Dictionary")
Set myObj2 = myObj
'
Environment("MyDictionary") = myObj2
Environment("MyDictionary").Add "x","value X"
Environment("MyDictionary").Add "y","value Y"
'
For Each strKey In myObj.Keys
MsgBox strKey & ": " & myObj.Item(strKey)
Next
MsgBox "myObj Items Count: " & myObj.Count
'
strKey="z"
MsgBox strKey & ": " & myObj.Item(strKey)
'
MsgBox "myObj Items Count: " & myObj.Count


In the above code (that can be executed in a QTP test case) there is only one Dictionary object, but three references to it: myObj, myObj2, and Environment("MyDictionary").

More importantly, this example points out why you should probably wrap a Dictionary object inside of a custom object that does some error checking: if you "read" a non-existant Dictionary element (as we do above using the non-existant 'z' key) the key and an Empty value is added to the Dictionary. (Seems to me that vbScript should throw an exception in that scenario, but it does not).


Post Extras: Print Post   Remind Me!   Notify Moderator  
Jared_Quinert
Junior Member


Reged: 10/02/01
Posts: 12
Loc: Melbourne, Australia
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #364599 - 03/07/07 10:07 PM

A quick question regarding classes -

When I create a QTP script and define a class in the script, all is good. If I then move the class definition out to a function library and associate the function library with the script, it doesn't seem to be able to find it. Is there something simple I'm missing? Have built frameworks before but am a QTP/VBScript newbie.

Thanks in advance,

Jared

--------------------
---------------------------
Software testing thoughts - http://www.quinert.com/blog/


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: Jared_Quinert]
      #364764 - 03/08/07 08:40 AM

Jarad wrote:
Quote:


snip...
When I create a QTP script and define a class in the script, all is good. If I then move the class definition out to a function library and associate the function library with the script, it doesn't seem to be able to find it.
snip...





Hum... I do this all the time, as each of my included function libs are wrapped in a custom class. So I am not sure what the problem is here.

Reply with the following info and I will give it a look:

1. What is the exact error message from the failing line of QTP script code that fails in its attempt to instantiate an object from the class defined in the included lib?

2. Slim down the script to just the bare number of lines of code need to demonstate the problem. Do the same for the included lib. Then ZIP just those two files (the QTP "script" can be added as just script.txt, I will then create a real test case using my QTP 8.2).

3. Also be precise in how you are including the lib. For example are you using ExecuteFile() or including the lib in the Test Resource tab?

Hopefully I will spot something. Oh, also include your version of QTP (I am using 8.2 at this time).

-Terry Horwath


Post Extras: Print Post   Remind Me!   Notify Moderator  
nimmala_rk
Newbie


Reged: 03/16/07
Posts: 12
Re: vbScript FAQ and Useful Resources *DELETED* [Re: thorwath]
      #366750 - 03/16/07 10:03 PM

Post deleted by Terry Horwath

--------------------
Rama Krishna


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: nimmala_rk]
      #366812 - 03/18/07 06:36 AM

Rama, while everyone likes to hear their effort is useful to others I ask that you and others please do not post raves, rants and other forms of content-free replies to this thread. These just clutter up the thread and make it difficult for others to find the real information.


Subject: Using Encoded vbScript Scripts in QTP

QTP currently (in all version up through this posting, which includes version 9.2) only supports including vbScripts in clear text. *.vbe scripts created using Microsoft's encoder/obfuscator from *.vbs scripts won't run under QTP. For more information refer to the following thread:

http://www.sqaforums.com/showflat.php?Cat=0&Number=366563

-Terry


Post Extras: Print Post   Remind Me!   Notify Moderator  
thorwathModerator
Veteran


Reged: 07/22/99
Posts: 3769
Loc: Grand Rapids, MI
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #367262 - 03/20/07 03:53 PM

Subject: Using Function Pointers in vbScript

Function pointers in vbScript? Who would have thought!

Well, the getRef() function is designed to return a reference to a procedure that can be bound to an event. And while there are some restrictions to using this function, especially in QTP (noted below), this capability may prove useful when you want to construct dynamic references to library functions.

The syntax for getRef() is (see online help for more details):

set funcPtr = getRef("functionName")

The first restriction is that "functionName" must be a text string that is the name of a function or sub that is currently in scope (i.e. in the current namespace where the getRef() statement is located). This feature would be much more useful if this restriction (which I found to be true in WSH as well as QTP) was not imposed.

A further QTP restriction occurs when trying to use the getRef() statement in a QTP script where the function being referenced is located in a library that is included by the script. The remainder of this article discusses that restriction, and a workaround for it.

This works:
Code:

'Script code, no included vbScript lib
'
Dim funcptr
'
Sub foo ()
msgBox "in foo()"
End Sub
'
Set funcptr = getRef("foo")
funcptr



While the following code fails (where lib1.vbs is included by the QTP test script):
Code:

'Script code START ***************************
'
Dim funcptr
'
Set funcptr = getRef("foo")
funcptr
'
'Script code END *****************************
'
'lib1.vbs code START *************************
'
Sub foo ()
msgBox "in foo()"
End Sub
'
'lib1.vbs code END ***************************


In the above code the failure occurs at the Set funcptr = getRef("foo") line, with an error message of "invalid procedure call or argument: 'getRef'". I can only guess why this fails, because clearly the foo() function is in scope (you can prove that yourself by calling it before the failing line of code). I am guessing is has something to do with the fact that QTP implements file inclusion in a manner that is not compatible with the interpreter's parm checking for the call to getRef(). But no matter, you are always in a grey area when the implementation is left up to each runtime environment (which is the case for file inclusion).

Now, here is one workaround to this failure (where lib1.vbs and lib2.vbs are included by the QTP test script):
Code:

'Script code START ***************************
'
Dim funcptr
'
Set funcptr = setFuncPtr("foo")
funcptr
'
Set funcptr = setFuncPtr("bar")
funcptr
'
'Script code END *****************************
'
'lib1.vbs code START *************************
'
Sub foo ()
msgBox "in foo()"
End Sub
'
function setFuncPtr(sFuncName)
set setFuncPtr = getRef(sFuncName)
end function
'
'lib1.vbs code END ***************************
'
'
'lib2.vbs code START *************************
'
Sub bar ()
msgBox "in bar()"
End Sub
'
'lib2.vbs code END ***************************


In the above code, the getRef() function is wrapped in a function, setFuncPtr(), arbitrarily contained in any included *.vbs file. I believe this wrapper function forces resolution later in runtime (I know that is a strange statement in an interpreted lang), OR that QTP bunches all code include in external libs into their own namespace. Whatever.

I include the 2nd lib, with the bar() sub, so that I could confirm that this workaround works when the function names, as text strings, specified by the test case reside in libs other than the one that contains the setFuncPtr() wrapper function.

This workaround was validated by me in QTP 8.2 and another forum member in version 9.2.

-Terry Horwath


Post Extras: Print Post   Remind Me!   Notify Moderator  
Jared_Quinert
Junior Member


Reged: 10/02/01
Posts: 12
Loc: Melbourne, Australia
Re: vbScript FAQ and Useful Resources [Re: thorwath]
      #367274 - 03/20/07 05:53 PM

My other response appears to have not turned up. I have managed to find out that the solution is to put a factory function in the script which defines the class.

So the function library which defines your class has to look like this:

Code:
   
Function getMyClassInstance
Set getMyClassInstance = New myClass
End Function



Class myClass
Dim fred

sub class_initialize
fred="Fred"
end sub
End Class




Then, instead of

Set a=New myClass

use

Set a=getMyClassInstance

Bizarre...

Jared

Edited by XFlibble (03/20/07 05:56 PM)


Post Extras: Print Post   Remind Me!   Notify Moderator  
Pages: 1 | 2 | 3 | >> (show all)



Extra information
10 registered and 98 anonymous users are browsing this forum.

Moderator:  IanFraser, thorwath, TReddy, AJ, Tarun Lalwani, mwsrosso 

Print Topic

Forum Permissions
      You cannot start new topics
      You cannot reply to topics
      HTML is disabled
      UBBCode is enabled

Rating:
Topic views: 37923

Rate this topic

Jump to

Contact Us | Privacy statement SQAForums

Powered by UBB.threads™ 6.5.5