Advanced IBM Rational Functional Tester, Java Scripting
Advanced IBM Rational Functional Tester, Java Scripting
Class Book
Advanced IBM Rational Functional Tester, Java Scripting
Course Outline
Module Module Module Module Module Module 1: 2: 3: 4: 5: 6: Regular Expressions Functional Tester API HelperSuper Classes Dynamic Object Handling Custom Verification Points Handling Non-Java/Browser Windows
Prerequisities
The prerequisities for this course is completion of either:
The online training class titled Essentials of IBM Rational Functional Tester, Java Scripting: The Basics The instructor-led course titled Essentials of IBM Rational Functional Tester, Java Scripting: The Basics And Java for IBM Rational Functional Tester
Course Materials
There are 2 books issued with this class:
Class Book Lab Book
Introductions
Your organization Your role Your background, experience
Software development experience Rational tools experience Testing experience
Regular Expressions
Functional Tester installs with Rational's lightweight regular expression class - import com.rational.test.util.regex.*; Sun's regular expression package is in JDK 1.4.x: - java.util.regex We will cover com.rational.test.util.regex.*
Regex: matches()
Regular Expression Syntax: public boolean matches(String strToCompare) /* The RE pattern is passed to the constructor to "compile" the regular expression. The match string is passed to the matches() method */ Regex pattern = new Regex("in"); boolean b = pattern.matches("Fox in Socks"); RE engine matches patterns without special characters. Returns true, since 'in' is a subset of 'Fox in Socks'
Regex: matches()
Selected Regex operators:
* + . ? | () [] {} (asterisk) (plus) (period) (question mark) (pipe) (parentheses) (square brackets) (curly braces)
Note: See the Functional Tester documentation for a more complete listing of regular expression operators.
Regex: matches()
Regex character class operator: []
used to match any one of several characters Regex pattern = new Regex("gr[ae]y"); pattern.matches("gray matter");
Returns true
pattern.matches("graey");
Returns false
Regex: matches()
Regex negated character class: [^]
[^] negated character class Regex pattern = new Regex("[A-E]-[^0-9]"); boolean b = pattern.matches("B-V");
Returns true
b = pattern.matches("B-5");
Returns false
Regex: matches()
Regex operator: . (period)
matches any single character Regex pattern = new Regex("212.240.9050"); boolean b =pattern.matches("212-240-9050"); b = pattern.matches("212 240 9050"); b = pattern.matches("212/240/9050")
Returns true
Regex: matches()
Regex operator: * (asterisk)
* matches 0 or more of the previous pattern Regex pattern =new Regex("[0-9]* Dalmations"); boolean b = pattern.matches("101 " + "Dalmations");
Returns true
b = pattern.matches("Red Dalmations");
Returns true
b = pattern.matches("101 Terriers");
Returns false
Regex: matches()
Regex operator: ? (question mark)
? matches 0 or 1 of the previous pattern
Regex pattern =new Regex ("https?://"); b = pattern.matches ("https://"); Returns true b = pattern.matches("http://"); Returns true b = pattern .matches("httpx://"); Returns false
Regex: matches()
Regex operator: + (plus)
+ matches 1 or more of the previous pattern Regex pattern = new Regex("a+d"); b = pattern.matches("aaaaad");
Returns true
b = pattern.matches ("d") ;
Returns false, since 'd' is not 1 or more a's followed by a 'd'
b = pattern.matches("bbbbbd");
Returns false, since 'bbbbbd' is not 1 or more 'a's followed by a 'd'
Regex: matches()
Regex operator: | (pipe)
| acts as a logical Or
Regex pattern =new Regex("Functional Tester|WinRunner|Silk"); boolean b =pattern.matches("They use SilkTest"); Returns true b = pattern.matches("They switched to Functional"); Returns false
Regex: matches()
Regex operator: () (parentheses)
() are used to group patterns Regex pattern = new Regex("a(bc)+d"); b = pattern.matches("abcbcbcbcd");
Returns true
b = pattern.matches("bcbcbcbcd");
Returns false
10
Regex: matches()
Regex operator: {} (curly braces)
{} match a pattern a defined number of times. x{n} match 'x' exactly n times. x{n,} match 'x' at least n times. x{n,m} match 'x' at least n times and not more than m times
b = pattern.matches("baaaad");
Returns false
b = pattern.matches("baaaad");
Returns true
Regex: matches()
Escaping regex operators
Regex pattern = new Regex("a[(]bc[)]d"); b = pattern.matches("a(bc)d");
returns true
b = pattern.matches("abcd");
returns false
11
Regex: matches()
POSIX character classes
Use character classes as match pattern Regex pattern = new Regex("[:digit:]"); b = pattern.matches("3");
Returns true
b = pattern.matches("a");
Returns false
Regex: getMatch()
public String getMatch()
Returns the part of the string that matched the pattern. String sRet = ""; Regex pattern = new Regex ("a*dd") ; b = pattern.matches ("baaaaadd") ; sRet = pattern.getMatch(); sRet= "aaaaadd"
12
Regex: getMatch()
public String getMatch(int n)
Returns the substring that matched one of the parenthesized subexpressions of the regular expression, in indexed order.
Regex pattern = new Regex("(value=)(\"[:alnum:]+\")"); boolean b = pattern.matches("value=\"hidden\""); System.out.println(pattern.getMatch()); System.out.println(pattern.getMatch(1)); System.out.println(pattern.getMatch(2)); getMatch() returns: value="hidden" getMatch(1) returns: value= getMatch(2) returns: "hidden"
Regex: Closure
Two types of closure
greedy: matches as many string elements as possible. reluctant: matches as few string elements as possible. Greedy closure is the default closure. Reluctant closure is indicated by a trailing '?' after the operators: +, *, ?, {m,n}
13
Regex: Closure
// greedy closure: Regex pattern = new Regex("j.*z"); b = pattern.matches("jazjazjaz"); ret = pattern.getMatch(); ret = "jazjazjaz" // reluctant closure: Regex pattern = new Regex("j.*?z"); b = pattern.matches("jazjazjaz"); ret = pattern.getMatch(); ret = "jaz"
Regular Expressions
Lab 1.1
14
ProcessTestObject
ScrollTestObject IScrollable
SubitemTestObject ISubitem
15
ProcessTestObject
Represents a Functional Tester-initiated process.
GUITestObject
Base class for modeling all objects in the software under test that have a GUI.
SubitemTestObject
Models subitems that are contained in other objects for example, lists.
16
//
17
18
getTestData()
used to capture any data that a data verification point can "see" returns the data as an ITestData interface usually requires more method calls
19
Object propObj = Button_Gosubmit().getProperty(".name"); String prop = propObj.toString(); System.out.println( prop ); / / return value: "Go button"
20
outerHTML: <DIV class=title id=title001 style="FONT-WEIGHT: bold"> Functional Tester TEST WEB PAGE </DIV> .text: Functional Tester TEST WEB PAGE
21
22
23
Hashtable dataTypes = tree().getTestDataTypes(); // return value: {tree = tree Hierarchy; // selected = selected tree Hierarchy}
24
ITestData
ITestDataText
ITestDataList
ITestDataTable
ITestDataTree
ITestDataElement
ITestDataElementList
ITestDataTreeNode ITestDataTreeNodes
25
26
27
Lab 2.1
ITestData
ITestDataText
ITestDataList
ITestDataTable
ITestDataTree
ITestDataElement
ITestDataElementList
ITestDataTreeNode ITestDataTreeNodes
28
29
Lab 2.2
30
ITestData
ITestDataText
ITestDataList
ITestDataTable
ITestDataTree
ITestDataElement
ITestDataElementList
ITestDataTreeNode ITestDataTreeNodes
31
32
ITestDataElementList selObj = listSel.getElements(); // Assumption: only 1 item is selected ITestDataElement selElem = selObj.getElement(0); String selText = selElem.getElement().toString(); System.out.println("list selection: "+ selText);
Lab 2.3
33
ITestData
ITestDataText
ITestDataList
ITestDataTable
ITestDataTree
ITestDataElement
ITestDataElementList
ITestDataTreeNode ITestDataTreeNodes
34
35
36
37
Lab 2.4
38
HelperSuper Classes
The default inheritance of your TestScript is:
RationalTestScript
"TestScriptHelper" Class
"TestScript Class
39
HelperSuper Classes
Functional Tester gives you the option of adding a HelperSuper Class to the hierarchy:
RationalTestScript
HelperSuper
"TestScriptHelper" Class
"TestScript Class
HelperSuper Classes
Uses of a HelperSuper class:
Any methods that you want inherited by any or all scripts can be put in the HelperSuper class. Methods of the RationalTestScript class can be overridden in the HelperSuper
40
HelperSuper Classes
HelperSuper classes follow certain rules:
1. A HelperSuper class may have any valid Java class name. 2. A HelperSuper class must extend RationalTestScript. 3. A HelperSuper file can be in the datastore root or subfolder, or an external .jar file. 4. Every participating TestScriptHelper must inherit from the HelperSuper class 5. The actual TestScript class itself requires no modification to inherit from a HelperSuper
HelperSuper Classes
Implementing a HelperSuper:
Create a HelperSuper class in your datastore: 1. Create a New Test Folder in your datastore (call it 'util') 2. Create a new Java class using the File -> New -> Other Dialog. 3. Choose Java in the left panel and Class on the right panel in the wizard 4. Choose the folder, the package, a class name, and choose a superclass of: com.rational.test.ft.script.RationalTestScript 5. Press the finish button
41
HelperSuper Classes
HelperSuper Classes
Choose Java folder and Class inside the folder in the wizard
42
HelperSuper Classes
HelperSuper Classes
Functional Tester creates a stubbed superclass with the characteristics you have requested:
package util; import com.rational.test.ft.script.Rational.TestScript; public class MyHelperSuper extends RationalTestScript { //insert code here }
43
HelperSuper Classes
Implementing a HelperSuper:
Make MyHelperSuper inheritance the default for all new scripts. Right-click on the project in the Functional Test Project view, and select Properties. Select 'Functional Test Project' and change the 'Script Helper Superclass' field to 'util.MyHelperSuper'
HelperSuper Classes
Implementing a HelperSuper
Set MyHelperSuper inheritance for preexisting TestScript
44
HelperSuper Classes
The Functional Tester Execution Framework
Functional Tester performs housekeeping tasks, before and after testMain(), is called Execution Framework Among these tasks, two methods are called before and after testMain() The sequence is: onInitialize(); testMain(); onTerminate();
HelperSuper Classes
The Functional Tester Execution Framework
Two methods, onInitialize() and onTerminate() are for your own initialization and termination tasks. You can override onInitialize() and onTerminate() in your HelperSuper class to handle, for example, application initialization and termination.
Another methods to override onObjectNotFound(); onAmbiguousRecognition(); onTestObjectMethodException();
45
HelperSuper Classes
The Functional Tester Execution Framework
package util; import com.rational.test.ft.script.RationalTestScript; import com.rational.test.ft.object.interfaces.ProcessTestObject; Public class MyHelperSuper extends RationalTestScript { ProcessTestObject pto = null; public void onInitialize() { pto =startApp("ClassicsJavaA"); } public void onTerminate() { if (pto.isAlive()) { pto.kill(); } } }
HelperSuper Classes
Lab 3.1
46
47
protected GuiTestObject Link_IslandAdventures() { return new GuiTestObject( getMappedTestObject("Link_IslandAdventures")); } protected GuiTestObject Link_IslandAdventures(TestObject anchor, long flags) { return new GuiTestObject( getMappedTestObject("Link_IslandAdventures"), anchor, flags); }
48
49
<MTO L=".MTO"> <Id>0.5vYm2Dr5yw0:1eHQrh:KNho7eA:8WW</Id> <Name>ClassicsJava</Name> <Parent/> <TO>TopLevelTestObject</TO> <Dom>Java</Dom> <Class>ClassicsJava</Class> <Role>Frame</Role> <Proxy>.java.jfc.JFrameProxy</Proxy> <Prop L=".MtoProp"> <Key>.captionText</Key> <Val L=".caption"> <Caption></Caption> </Val> <Wt>75</Wt> </Prop> </MTO>
Advanced IBM Rational Functional Tester, Java Scripting
50
51
tree().click(atPath("Composers->Schubert->Location (PLUS_MINUS)")); tree().click(atPath("Composers->Haydn->Location (PLUS_MINUS)")); tree().click(atPath("Composers->Bach->Location (PLUS_MINUS)")); tree().setState(Action.vScroll(128)); tree().click(atPath("Composers->Beethoven-> Location(PLUS_MINUS)")); tree().setState(Action.vScroll(176)); tree().click (atPath("Composers->Mozart->Location (PLUS_MINUS)"));
This means that 7 tree() TestObjectS are created in the script process -- consuming the resources of 7 objects
52
53
54
55
56
57
String baseline = "Bill Wu"; /* code to select a recording and login as Bill Wu */ String actual = (String) text().getProperty("text") ; vpManual.("UserName", baseline, actual).performTest();
double baseline = 19.99; String actual = ((String)totalAmount().getProperty("text")).substring(1); Double b = new Double(baseline); Double a = new Double(actual); vpManual ("TotalAmount", b, a).performTest();
58
59
60
Passes
Fails
61
Fails
62
63
64
Returns false
65
returns false
Logs a pass
66
On first playback, brings up VP wizard and creates aVerification Point in the Script Explorer on any mapped TestObject
second signature:
On first playback, brings up VP wizard and create aVerification Point in the Script Explorer on the passed TestObject
67
Lab 5.1
68
Non-Java/Browser Windows
While recording, Functional Tester only recognizes actions performed against Java and browser windows There may be cases where you need to perform actions against other types of windows Functional Tester API has 2 interfaces you can use to perfom actions against any window: IScreen IWindow
69
Non-Java/Browser Windows
IScreen and IWindow
Limited set of methods The IScreen API has no methods that retrieve data You cannot cast from IScreen to TestObject
Non-Java/Browser Windows
IScreen
An interface designed to perform actions against the currently active window. Since IScreen is an interface, there is no constructor. You get an IScreen by calling getScreen() a method in RationalTestScript
70
Non-Java/Browser Windows
Methods that perform GUI actions
.click(), click(Point), click(Modifiers), doubleClick(), drag(), mouseMove(), nClick() inputChars(String) inputKeys(String) inputKeys and inputChars send characters to the current active window wherever the cursor is focused If you need to send characters to a particular object within a window, you might have to add navigational actions
Non-Java/Browser Windows
IScreen
Bad News There are no methods in IScreen that retrieve interesting information (properties, data) from a window
isEnabled(), isShowing(), hasFocus() getMousePosition(), getChildAtPoint()
Good News There are methods in IWindow that allow you get limited information about a window
71
Non-Java/Browser Windows
IWindow
IScreen has methods that return an IWindow getActiveWindow(); windowFromHandle( long ); windowFromPoint( java.awt.Point ); IScreen scrn = getScreen(); IWindow win = scrn.getActiveWindow(); Point p = scrn.getMousePosition(); win = scrn.windowFromPoint(p);
Non-Java/Browser Windows
IWindow
More Good News RationalTestScript has a method that returns an array of all the top level windows on the screen: getTopWindows();
IWindow[] allWins = getTopWindows();
72
Non-Java/Browser Windows
IWindow
Getting Information from a Window IWindow has methods that query windows: getText() - returns the window caption . getWindowClassName() getHandle() - return the native window handle (hWnd on Windows). getId() - returns the Windows control ID. getPid() - returns the process ID for the window
Non-Java/Browser Windows
IWindow
GUI actions If the IWindow is a TopLevelWindow, you can call these methods: close() activate() maximize() minimize() contextHelp() - activates the window's contextsensitive Help mode.
73
Non-Java/Browser Windows
IWindow
Related Window Objects IWindow has methods that return IWindow references to objects related to the same window: IWindow[] getChildren(); IWindow getparent(); IWindow getTopParent(); IWindow getOwned(); IWindow getOwner();
Non-Java/Browser Windows
IWindow
What if you need to get data from an object? There are no methods in IWindow that do this If you can copy the data to the clipboard, you can use Java to access the clipboard
74
Non-Java/Browser Windows
Accessing the Clipboard
Retrieve the Contents of the System Clipboard import java.awt.datatransfer.*; import java.awt.Toolkit; Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable t = clipboard.getContents(null); String data = null; try { data = t.getTransferData(DataFlavor. stringFlavor).toString(); } catch (UnsupportedFlavorException ufe) { } catch( IOException ioe ) { }
Non-Java/Browser Windows
Accessing the Clipboard
Send Text to the System Clipboard
import java.awt.datatransfer.*; import java.awt.Toolkit; Clipboard clipboard = Toolkit.getDefaultToolkit() .getSystemClipboard(); String data = "How now brown cow"; StringSelection ss = new StringSelection( data ); clipboard.setContents( ss, ss );
75
Non-Java/Browser Windows
Lab 6.1
76