Skip to main content

Testing Custom Java Controls with Rational Functional Tester's getProperty and invoke Methods

Tim Snow (tsnow@us.ibm.com), Technical Lead, IBM
Tim Snow
Tim Snow leads the Automation Services team of the Notes Client. For the past two years, he has spearheaded the conversion to IBM Rational Functional Tester. Tim has a diverse background, ranging from programming in Java and C++, to designing expert systems, to a Ph.D. in analytic philosophy.

Summary:  Custom Java controls, or those controls that are not part of the standard Java library, present challenges for the GUI automation tester. This article explains how to create automation that uses these types of controls by explaining the two methods that IBM Rational Functional Tester provides to handle them: getProperty and invoke.

Date:  31 Oct 2006
Level:  Advanced
Activity:  647 views

IBM® Rational® Functional Tester provides interfaces that make it easy to manipulate standard Java™ controls. For example, you can easily get or set the text of a Swing text box using the getText and setText methods in the Rational TextGuiTestObject interface. Nonstandard or custom controls, on the other hand, are more difficult to automate with any GUI automation tool, including the Rational Functional Tester. Custom controls are controls that aren't a part of the standard widget set (AWT or Swing, for example) but, instead, are controls that the developer of the application created from scratch. Rational Functional Tester developers weren’t aware of these controls, so they could not anticipate the methods you need to manipulate them, and thus can't provide an interface that includes all of these methods. Therefore, to test them, you need to get direct access to information about how the control works from the control itself. Fortunately, Rational Functional Tester provides a way to do this by using the getProperty and invoke methods.

An example of a custom control is the Java applet that Figure 1 shows. This is the Editor applet included in Lotus Notes.


Figure 1. The Lotus Notes Editor applet
Lotus Notes Editor applet

This applet displays a field where the user can enter rich text (text that you can format as bold, italic, in colors, and so forth). The user can control the appearance of the text by using the buttons and list boxes across the top of the applet. These buttons are not standard controls. That is, they are not Swing or AWT buttons, but proprietary inventions of the Lotus developers. Their package and class name, com.lotus.app.MultiImageButton, reveals this. Obviously, a class in such a package is not a standard control, so Rational Functional Tester won't be able to provide an interface that includes everything you need to manipulate it.

However, even though these buttons are not standard controls, Rational Functional Tester still recognizes them by using the most general class available to represent them, namely GuiTestObject. But in most instances, this will not be good enough. The problem is that you need more information about the controls and more ways to manipulate them than is provided by GuiTestObject directly. For example, although GuiTestObject provides a method that allows you to click the button, it won't provide a getText method to get the name of the button (to distinguish the Bold button from the Italic button, for example), and it won't provide an isSelected method to determine whether a particular button is selected. Yet these are things that you will need to know to test this applet thoroughly. Therefore, you must use the Rational Functional Tester getProperty and invoke methods to get the information directly from the controls.

This article shows you how to use Rational Functional Tester to test custom Java controls. It focuses on the example of this Editor applet created by Lotus, but you can apply the principles to any custom Java class, whether embedded in a Web page or not.

The Object Map

When you approach automating the Editor applet, the first thing you need to do is to map its objects. To do so, just follow these steps:

  1. Create a new script.
  2. Open the Object Map.
  3. Select Insert Test Object.
  4. Highlight a control on the page.
  5. Choose Include All Objects on Selected Page.
  6. Click Finish.

This adds all of the objects on the page to My Object Map, as shown in Figure 2.


Figure 2. The Object Map from the Editor applet
Object Map

Note:
In this case, because you are testing an applet, you have to select the Java domain when you add these objects. Otherwise, the result would be only one object corresponding to the applet, rather than many objects corresponding to each Java control within the applet. This is not necessary if you are testing stand-alone Java applications.

As you can see, in this case, Rational Functional Tester could identify that each of the controls on the applet are separate GUI objects. Often, though, custom controls aren't made up of controls that Rational Functional Tester can identify as separate objects. For example, Lotus Notes has another applet called the Action Bar applet that holds a number of Action buttons, as Figure 3 shows.


Figure 3. The Action Bar applet
Action Bar applet

When mapped, this applet produces only a single test object, as shown in Figure 4.


Figure 4. The Object Map of the Action Bar applet
Object Map of the Action Bar applet

The reason for only a single test object is that the buttons in this applet aren't really buttons, in that none is a separate GUI object. Instead, the Action Bar applet "draws" each object on top of the Action Bar. The Action Bar applet also keeps track of the boundaries of each button. When a user clicks inside of the Action Bar, the applet intercepts that click and figures out which button the user's mouse is over, given its boundaries. This applet is much trickier to automate because of this, which is why I focus on the simpler Editor applet for most of this article. However, because this problem of owner-drawn controls is common, I return to the Action Bar applet at the end of the article to show you how you can use the Rational invoke method as an alternative, to get around that problem.

Because Rational Functional Tester recognizes the individual buttons of the Editor applet, testing it is a lot easier. The buttons register as GUI test objects in the Object Map, and they are assigned indexes that correspond to their positions in the applet. Therefore, you can use the GuiTestObject click method, in conjunction with the index, to click any particular button. For example, to click the Bold button, you could find the button with the index of 1 (one) in the Object Map, transfer that object to the script, and then call the click method.

However, it would probably be better to find the button by finding a particular name rather than relying on the index, just in case the developers switch the order of these buttons. But this information isn't directly provided by any GuiTestObject method (there is no getText method in GuiTestObject that provides the name of one of these buttons, for instance). Therefore, you must query the buttons directly to get this information. As it turns out, there are two ways of getting this information with Rational Functional Tester: either by querying the button's properties or by invoking a method. Let's turn to the first of these to illustrate.


Getting the properties of a control

Rational Functional Tester gives you a way to get particular properties of a control: the getProperty method of TestObject. Thus, for example, if you happen to know that the Editor applet's buttons have a property called toolTipText that contains the name of the button, you can get that name by using the following code.


Listing 1: Get the properties of a button
String buttonName=(String)multiImgButton().getProperty("toolTipText");

This code calls getProperty on the GuiTestObject multiImgButton, which is the Bold button in your Object Map. The getProperty method returns an instance of the class Object, so you must cast the result into the appropriate type, which, in this case, is a string. After running this code, buttonName is set to bold, and you can identify this button by name.

As you can see, it is pretty easy to get the properties of a test object when you know the name of the property you are looking for. The trick is knowing the names of the properties. It is unlikely that you could have guessed that the name of the property you needed was toolTipText. Thus, to find out what properties a control provides, you can get all of the properties of the control and print them, using this utility method:


Listing 2: Get all of the properties of a control
				 
/**
 * Prints out all the properties of an object to the console
 * @param to	object whose properties you want to print
 */
public static void printProperties(TestObject to) {
	Hashtable htable = to.getProperties();
	int i = 1;
	Enumeration eKeys = htable.keys();
	Enumeration eElems = htable.elements();
	while (eKeys.hasMoreElements()) {
		System.out.println("Property " + i + ": name=" 
			+ eKeys.nextElement() + "; value=" 
			+ eElems.nextElement());
		i++;
	}
}

This method prints all of the properties of a test object (TestObject). It works by calling the test object's getProperties method, which returns a hash table with all of the control's properties and all of the values of those properties. The method then simply prints all of this data. You can call it with this command, passing the GuiTestObject from the Object Map: printProperties(multiImgButton());

The properties display in the console window. If you pass one of your buttons in the Editor applet, you get the following output:


Listing 3: Output
				 
Property 1: name=visible; value=true
Property 2: name=foreground; value=java.awt.Color[r=0,g=0,b=0]
Property 3: name=ignoreRepaint; value=false
Property 4: name=minimumSizeSet; value=false
Property 5: name=focusTraversalKeysEnabled; value=true
Property 6: name=location; value=java.awt.Point[x=0,y=2]
Property 7: name=focusTraversable; value=true
Property 8: name=background; value=java.awt.Color[r=255,g=255,b=255]
Property 9: name=name; value=canvas0
Property 10: name=selected; value=false
Property 11: name=backgroundSet; value=false
Property 12: name=toolTipText; value=Bold
Property 13: name=maximumSizeSet; value=false
Property 14: name=lightweight; value=false
Property 15: name=font; value=com.rational.test.ft.value.
 	FontInfo[name=Dialog,style=0,size=12]
Property 16: name=opaque; value=true
Property 17: name=mousePosition; value=java.awt.Point[x=14,y=13]
Property 18: name=alignmentY; value=0.5
Property 19: name=alignmentX; value=0.5
Property 20: name=preferredSizeSet; value=false
Property 21: name=doubleBuffered; value=false
Property 22: name=maximumSize; value=java.awt.Dimension[width=32767,height=32767]
Property 23: name=focusOwner; value=false
Property 24: name=cursorSet; value=false
Property 25: name=preferredSize; value=java.awt.Dimension[width=27,height=27]
Property 26: name=foregroundSet; value=false
Property 27: name=focus; value=false
Property 28: name=locationOnScreen; value=java.awt.Point[x=173,y=179]
Property 29: name=fontSet; value=false
Property 30: name=curImage; value=0
Property 31: name=size; value=java.awt.Dimension[width=27,height=27]
Property 32: name=enabled; value=true
Property 33: name=y; value=2
Property 34: name=x; value=0
Property 35: name=bounds; value=java.awt.Rectangle[x=0,y=2,width=27,height=27]
Property 36: name=minimumSize; value=java.awt.Dimension[width=27,height=27]
Property 37: name=valid; value=true
Property 38: name=width; value=27
Property 39: name=filtered; value=0
Property 40: name=showing; value=true
Property 41: name=displayable; value=true
Property 42: name=height; value=27
Property 43: name=focusable; value=true
Property 44: name=class; value=lotus.notes.apps.editorpanel.MultiImgButton

You can peruse this list, looking for a particular property that might meet your needs. When you see the one you need, you can use the name as the input for the getProperty method, which will return the property's value.

Another useful property of the buttons in this applet is the selected property. This will tell you whether a particular button, such as the Bold button, is currently selected, so you can tell whether the text you enter into the applet is supposed to be bold or not. You can see from the output that this property is currently false, meaning that any text typed in the applet will not be bold. To use this information in a script, however, you can get the property easily by using the getProperty method like so:


Listing 4: Get the selected property
				
boolean isButtonSelected = 
	((Boolean)multiImgButton().getProperty("selected")).booleanValue();

This is very similar to the preceding code that got the name of the button. However, an extra complication is that the value returned is a primitive, not an object. To make the data useful to your script, you need to first cast the return value to a Boolean object, and then convert that object to a primitive Boolean. You must do this with any other primitives, such as ints, that you receive as output from getProperty.

As you can see, there are many other properties of this object that might prove useful for testing this applet. However, properties can take you only so far. Usually, a Java control has many more methods than properties, and any method that requires arguments can't be a property. Often, you want direct access to a control's methods. Rational Functional Tester gives you a way to get that access, using TestObject's invoke method. Let's look at that now.


Invoking the methods of a control

You can use the invoke method of the Rational Functional Tester TestObject interface to call any methods of a Java control. Because every Java property has a get and set method associated with it, you can do everything that you can do with getProperty with invoke. But the invoke method can do much more, as you shall see.

To illustrate, let's consider another control in the Editor applet, the Color Canvas drop-down menu shown in Figure 5.


Figure 5. The Color Canvas control
Color Canvas control

If you choose a color in this control, the text in the Editor applet appears in that color. To test the Editor applet, you need to be able to get and set the color in this control.

Although this control looks like a Swing or AWT combination box, it isn't. Instead, it is a custom control created by Lotus developers for choosing colors. Because it is not a standard control, Rational Functional Tester does not know how to manipulate it, so you must use the control's methods to automate it.

To start, you need to know what methods this control has. You could look at the source code or use Java™ Reflection™ to find out, but, as with the properties, you can also get this information using Rational Functional Tester. Simply use this utility method:


Listing 5: Get all of the methods of a control
				 
/**
 * Prints out the methods of an object (omitting methods from java.lang.Object)
 * @param to	object whose methods you want to print
 */	
public static void printMethods(TestObject to) {
	MethodInfo[] m = to.getMethods();
	for (int i = 0; i < m.length; ++i) {
		System.out.println("Method " + i + ": name=" + 
			m[i].getName() + "; signature=" 
			+ m[i].getSignature());
	}
}				

This utility method gets all of the methods of a control and displays them on the console. To do this, it uses a method in TestObject called getMethods, which returns an array of MethodInfo objects. It then cycles through all of the elements of this array, displaying the name of the method and its signature.

You can call this utility just as you did the printProperties method previously, passing in the GuiTestObject returned by Rational Functional Tester from the Object Map (in this case called colorCanvas), like this:


Listing 6: Call printMethods utility
				 
printMethods(colorCanvas());

The utility method diplays all of the methods that you can use on this control.

When I run this piece of code, it displays 307 methods! These include not only all of the methods defined in this class, but all of the methods that the class inherits from its super classes also. Many of these will be irrelevant for your purposes, but the two you need are at the top:

Method 1: name=getColor; signature=()Ljava/awt/Color;

Method 2: name=setColor; signature=(Ljava/awt/Color;)V

If you want to get and set the color of this control, you must use the invoke method to call these two methods of the control. You obviously need the name of the method that you want to call to use the invoke method, but you also need any arguments that the method requires and its return value. Hence, the need to know the method's signature.

The signatures display in JNI (Java™ Native Interface) format. The types of the parameters of the method are listed inside of the parentheses, and the type of the return value is listed at the end. Table 1 is a chart from the Java documentation for the invoke method that explains the symbols for the types.


Table 1. JNI format for method signatures
CodeType
Zboolean
Bbyte
Cchar
Sshort
Zboolean
Iint
Jlong
Zboolean
Ffloat
Ddouble
Vvoid
L fully-qualitied-class;; For example: Ljava.lang.String;

The first relevant method, getColor, has a signature of ()Ljava/awt/Color;. The parentheses are empty, which indicates that the method takes no arguments. It does return an object of type of java.awt.Color, however, as indicated by the L and the semicolon that show where the name of the object ends. The second method, setColor, has a signature of (Ljava/awt/Color;)V. Not surprisingly, it takes an argument of type of java.awt.Color, which is the color to set the control to. However, it returns nothing, as indicated by the V, which stands for void.

The invoke method is overloaded. It has two forms, depending on whether or not you need to pass arguments to the method you are calling. The form that calls methods without arguments is much easier, so let's start with that.

To use the first form of the invoke method, all you need to do is to pass to invoke the name of the method that you want to call. The following code illustrates its use, invoking the getColor method of ColorCanvas, which takes no arguments:


Listing 7: Tell invoke the name of the method you want to call
java.awt.Color color = (java.awt.Color)colorCanvas().invoke("getColor");

getColor returns a java.awt.Color object. Be sure to catch that in a variable, because that is the information you were after in the first place. But the invoke method, such as getProperty, returns an object of class Object. Therefore, to use it, you need to cast that to a java.awt.Color object.

Note:
As you can see, this call to invoke is very similar to a call to getProperty. That's not surprising when you consider that all properties of a Java object have get and set methods. In fact, in this case, color is a property of the ColorCanvas control, so you could have used the getProperty method to get the same information.

Setting the color is a bit more complex than getting the color. Because setColor requires an argument, you'll have to use the second overloaded form of invoke, passing it three things:

  • The name of the method you want to call
  • A string representing the method's signature in JNI syntax
  • An array of objects containing the actual value of the arguments you want to pass

To call the setColor method of a ColorCanvas control from Rational Functional Tester, the first thing you need to do is to look at the signature and determine what arguments you need to pass to setColor. In this case, the method requires only one argument: the color you want for the text. To call the method, you'll need to create an object of that color to pass to the control. However, the invoke method requires that you put that object in an array of objects, because any particular method could have more than one argument to pass. Therefore, you have to wrap your argument into an array, and then pass it to the invoke method, like this:


Listing 8: Wrapping the method in an array
				  
Object [] color = {java.awt.Color.red};
colorCanvas().invoke("setColor", "(Ljava.awt.Color;)V", color);

In this way, you can use the invoke method to set the color of the text in the Editor applet to whatever color you want.

Although this use of the invoke method works fine in a technical sense, there is still a problem: You have manipulated the GUI in a way that the user can't, yet the whole point of GUI automation is to make sure that the GUI works as the user would use it. Thus, this example isn't very realistic, especially if you are trying to trying to test the GUI of the ColorCanvas control itself, rather than just the text of the applet. Therefore, it is better to write more complex code to click the control and choose a color from the resulting display. In the next section, you'll see a more complex and more realistic example of using the invoke method, which shows how much more coding is usually involved when trying to manipulate a custom Java control as the user is likely to do.


A more complex example

Let's look at the more complex example of the Action Button applet. This example is useful not only because it shows how you can manipulate a control that Rational Functional Tester knows nothing about, but also because it demonstrates how to get and use coordinates to manipulate controls. This is something you often need to do when testing custom controls.

Figure 6 reminds you what the Action Button applet looks like.


Figure 6. The Action Bar applet again
The Action Bar applet again

Rational Functional Tester treats this control as just one big rectangle. You'll recall that when it is mapped, it returns only one control, as Figure 7 shows.


Figure 7. The Object Map for the Action Bar applet again
The Object Map for the Action Bar applet again

Rational Functional Tester cannot distinguish among the different buttons that this control displays. Therefore, you can't simply use the objects returned from the Object Map to click a particular button, as you could with the Editor applet.

Rather, to allow your automation to click these buttons, you need the coordinates of each one. Then, you can use these coordinates to tell the Rational Functional Tester click method to click a specific point inside the button. You could hardcode the coordinates of the buttons, but that would be unreliable, because the sizes change according to the text. A much more reliable way to get the coordinates is to use the methods of the control itself to determine the size of each button. To do this, you need to use the Rational Functional Tester invoke method.

The first thing that you'll need to do is to figure out which of the control's methods you can use to solve your problem. As an example, I ran the utility method printMethods (from the previous section) and found a method that provides the width of any particular button. Here is what the display showed:


Listing 9: Find out which control methods you can use
				 
Method 17: name=calculateButtonWidth; signature=(I)I

Using calculateButtonWidth, you can determine the X coordinate of any particular button relative to the applet by adding the widths of all the previous buttons. For example, the X coordinate of the Send as Email button is equal to the width of the Save Document button plus the width of the Close Document button. You can get the X coordinate of the Send as Email button by using this code:


Listing 10: Get the coordinate of the Send as Email button
				
int iButtonIndex = 2;
for (int i = 0; i < iButtonIndex; i++) {
	x += ((Integer)actionBar().invoke("calculateButtonWidth", 
		"(I)I", new Object[] {new Integer(i)})).intValue();
}

Furthermore, you can get the height of the buttons by getting the height of the applet. With these pieces of information, you can calculate a point to click for a particular button. Here is a general method that clicks any button in an Action Bar applet.


Listing 11: Method to click any button in the Action Bar applet
				 
public void clickActionBarAppletButton(int iButtonIndex, GuiTestObject actionBar) {
	int x = 0, y = 0, width = 0, height = 0;
	
	// **** CALCULATE x coordinate  ****
	for (int i = 0; i < iButtonIndex; i++) {
		x += ((Integer)actionBar.invoke("calculateButtonWidth", 
			"(I)I", new Object[] {new Integer(i)})).intValue();
	}

	// **** CALCULATE width  ****
	width = ((Integer)actionBar.invoke("calculateButtonWidth", 
		"(I)I", new Object[] {new Integer(iButtonIndex)})).intValue();

	// **** CALCULATE y coordinate ****
	y = 0;
		
	// **** CALCULATE height ****
	height = (int)actionBar.getScreenRectangle().getHeight();

	Point pointToClick=new Point(x + width/2, y + height/2);
	actionBar.click(pointToClick);
}

This method calculates where the middle of any particular button is, relative to the actionBar control itself, and then clicks that point.

This trick of calculating coordinates to determine where to click inside of a custom control is important to keep in mind. Often, you will find that not all pieces of a custom Java control are available to you in the Object Map. When this happens, you often find that the control itself has methods that you can use to calculate where components are located. Then it becomes merely a matter of simple arithmetic to calculate coordinates that you can use to derive a point to tell Rational Functional Tester where to click.

Note:
Sometimes, Rational Functional Tester doesn't map all of the components that it can recognizes. In these cases, you can try to find the components by searching the descendents of the control that Rational Functional Tester does map by using either getChildren or the find method. In fact, the Action Bar applet is even more complex than I suggested previously, because it is composed of several component panels, none of which, unfortunately, matches the individual buttons. Instead, a descendent of the parent applet is a panel that holds all of the buttons and interprets which button is clicked when the user clicks the panel. So in reality, you must call the invoke method on a child of a child of the Action Bar applet, rather than the Action Bar applet itself, to calculate the width of the buttons. I simplified the previous example to make it clearer, but it is good to keep in mind that you may be able to search the descendents of your custom Java controls to try to find components that may not map, yet may provide additional methods and properties that you can use.

As you can see from this example, automating custom controls can get quite complex. Sometimes, controls have exactly the methods that you need. And sometimes, they don't. When they don't, you need to create the information you need by manipulating the data that you can get from the control.


Putting it all together into widget classes

Now that you have generated the code to manipulate these custom controls, you need to put it where it is accessible to your script writers. Obviously, you won't want to reproduce this complex code in every script for clicking a button. Rather, you'll want to make this code available in general methods of centralized classes that any script can use. Specifically, you need to create widget classes for these controls. (See the developerWorks article titled "Wrapping calls to the Rational Functional Tester API in Resources for a description). In this way, you can hide the details from your users, thereby making your automation less error-prone.

You can now move your methods for clicking a button in the Action Bar into an Action Bar widget that looks something like this:


Listing 12: Moving methods into a widget class
				 
public class ActionBarApplet {

	private GuiTestObject actionBar=null;

	public ActionBarApplet(GuiTestObject gto) {
		actionBar = gto;
	}

	public void clickButton(int iButtonIndex) {
		int x = 0, y = 0, width = 0, height = 0;

		// **** CALCULATE x coordinate  ****
		for (int i = 0; i < iButtonIndex; i++) {
			x += ((Integer)actionBar.invoke("calculateButtonWidth", 
				"(I)I", new Object[] 
					{new Integer(i)})).intValue();
		}

		// **** CALCULATE width  ****
		width = ((Integer)actionBar.invoke("calculateButtonWidth", 
			"(I)I", new Object[] 
				{new Integer(iButtonIndex)})).intValue();

		// **** CALCULATE y coordinate ****
		y = 0;

		// **** CALCULATE height ****
		height = (int)actionBar.getScreenRectangle().getHeight();

		Point pointToClick=new Point(x + width/2, y + height/2);
		actionBar.click(pointToClick);
	}
}

With this class, your users can construct an Action Bar applet with the GuiTestObject returned from the Object Map, and then easily tell Rational Functional Tester to click a button by using the clickButton method. Of course, you would want to add more methods to this class, including getNumberOfButtons and getButtonName. After you have added these methods, you can include error checking and other conveniences for your users (by overloading clickButton, for example, so the user can enter the button name as a string rather than relying on the index).

Here is the beginning of an Editor applet class, which incorporates the code that you produced earlier:


Listing 13: Beginninig of code for an Editor applet class
				 
public class EditorApplet {

	private GuiTestObject editor;

	public EditorApplet(GuiTestObject to) {
		editor=to;
	}

	public void typeKeys (String s) {
		getCRTEditor().click();
		RationalTestScript.getScreen().inputKeys(s);
	}

	public boolean isBold() {
		return ((Boolean)getBoldButton().
			invoke("getSelected")).booleanValue();
	}

	public void setBold() {
		if (!isBold())
		this.getBoldButton().click();
	}

	public void unsetBold() {
		if (isBold())
			this.getBoldButton().click();
	}

	public java.awt.Color getColor() {
		return (java.awt.Color)getColorSelector().invoke("getColor");
	}

	public void setColor(java.awt.Color color) {
		getColorSelector().
			invoke("setColor", "(Ljava.awt.Color;)V", 
				new Object[] {color});
	}
	public GuiTestObject getCRTEditor() {
		return (GuiTestObject)editor.find(
			SubitemFactory.atDescendant(".class",
				"lotus.notes.apps.editor.CRTEdit"))[0];
	}

	public GuiTestObject getBoldButton() {
		//Bold is first button:
		//0.2.0.0  = lotus.notes.apps.editorpanel.MultiImgButton
		return (GuiTestObject)editor.getChildren()[0].
			getChildren()[2].getChildren()[0].getChildren()[0];
	}

	public TestObject getColorSelector() {
		return (GuiTestObject)editor.find(
			SubitemFactory.atDescendant("class","ColorCanvas"))[0];
	}
}

Note:
Nothing is actually mapped in this class. Instead, users pass in a GuiTestObject corresponding to the top-most Java class of the applet, and you search for all of the components dynamically. This helps to make the Editor applet more generalized.

A script can now use this widget class by including code similar to the following:


Listing 14: Code for script to use with widget class
				 
TestObject to = edit_applet(); //get the TestObject from the Object Map
Editorapplet editor = new EditorApplet(to); //construct the widget

editor.setBold();
editor.setColor(java.awt.Color.RED);
		
editor.typeKeys("testing");
System.out.println(editor.isBold());

As you can see, this greatly simplifies the use of these custom controls. Of course, as I already mentioned, there are many more methods that your users will want from these widgets. By using the invoke and getProperty methods, you can give them what they need.


Best practices for using these methods

Custom controls can be intimidating, but Rational Functional Tester gives you powerful tools to work with them. The getProperty and invoke methods are usually sufficient to tackle any problem that Java custom controls present. You can use getProperty to get most of the information you need, but if the information you need is not a property or if the method you need to call requires an argument, you can use the invoke method, instead.

Both getProperty and invoke are similar in that they allow you to call the methods of the control itself, rather than using the intermediary interfaces provided by Rational software. This gives you a lot of power -- power that you need to test custom controls. But be careful not to misuse this power. It is best to use these methods to get information about a control that you can then use to figure out how to tell Rational Functional Tester to manipulate the control as the user would. In other words, it is good practice to avoid using the set methods of the Java control or other methods that can manipulate the control in ways that a user could not. Your testing will be better and more comprehensive if you abide by this policy.

When automating the testing of any large Java application, you are bound to run across custom controls. Using the Rational Functional Tester getProperty and invoke methods, it is relatively straightforward to create your own calls to manipulate these controls. After you wrap these calls into a widget class, your script writers can write automation scripts that use these controls just as easily as they can to test standard Java controls.


Resources

Learn

Get products and technologies

Discuss

About the author

Tim Snow

Tim Snow leads the Automation Services team of the Notes Client. For the past two years, he has spearheaded the conversion to IBM Rational Functional Tester. Tim has a diverse background, ranging from programming in Java and C++, to designing expert systems, to a Ph.D. in analytic philosophy.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational
ArticleID=170579
ArticleTitle=Testing Custom Java Controls with Rational Functional Tester's getProperty and invoke Methods
publish-date=10312006
author1-email=tsnow@us.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers