Problem: Domain dependency prevents reuse of scripts
Whether test automation developers create scripts though the mechanism of record-playback or conventional descriptive programming, the test scripts and reusable functions get tied to the underlying domain of the application under test. So how do we make sure that the effort of writing functionality — setting text to an Edit Box, for example — is not repeated each time that there is a shift in the domain? Today, you might be writing test scripts for a web-based application, and the domain is recorded or scripted as HTML each time. Later, you might need to use the same functionality that you coded earlier but across a Java-based application.
When we use the record-playback mechanism, all of the test objects that the application interacts with are recorded and stored in the IBM® Rational® Functional Tester object map. Figure 1 shows an example of this, where the application domain gets hard-coded as Java.
Figure 1. An object map with Java as the application domain
Similarly, if the test scripts are developed by using the descriptive programming mechanism, the functions get tied to a particular application domain. In such a case, it becomes challenging to make the test functions reusable.
Therefore, it is better to make the script and the underlying test object independent of the application domain.
Solution: Use descriptive programming for cross-domain compatability
Rational Functional Tester offers a dynamic mechanism of getting a reference to the test objects during script playback. The find() API makes this possible, because it refers to the test object in the application under test without having it recorded or hard-coded in the test object map. This API finds the parent or top-level test object and looks for a matching child object.
Use the find() API to identify the domain or top-level object
Considering this, the test automation framework through descriptive programming and using the find() API can help identify the domain or top-level object of the application under test and find a matching child test object under it, accordingly. The code in Listing 1 illustrates this.
Listing 1. Set the test domain value for the current application
String myDomainName = ""; //For HTML Browser - Set the Application Domain Name myDomainName = "Html.HtmlBrowser"; OR //For HTML Dialog - Set the Application Domain Name myDomainName = "Html.Dialog"; OR //For Swing JDialog - Set the Application Domain Name myDomainName = "javax.swing.JDialog "; OR //For Swing JFrame - Set the Application Domain Name myDomainName = "javax.swing.JFrame"; OR //For Custom Parent Objects - Set the Application Domain Name myDomainName = " com.ibm.retail.rma.res.ui.config.MasterAgentInfoDlg "; |
In Rational Functional Tester code when the application domain has been set, the top-level test object can be parsed to parent object type that it maps to. This is illustrated in the code snippet in Listing 2. In this example, if the domain is HTML Browser, the top-level object is parsed to BrowserTestObject; if the domain is HTML Dialog, the top-level object is parsed to TopLevelTestObject, and so on.
Listing 2. Parse the parent object to application domain
/* Parse the Top Level Test Object to the corresponding test object type based
* on the domain name that was set
*/
TestObject myDomain;
if (myDomainName.equalsIgnoreCase("Html.HtmlBrowser")) {
myDomain = (BrowserTestObject)
returnTO(".class", "Html.HtmlBrowser");
}
else if (myDomainName.equalsIgnoreCase("Html.Dialog")) {
myDomain = (TopLevelTestObject)
returnTO(".class", "Html.Dialog");
}
else if (myDomainName.equalsIgnoreCase("javax.swing.JDialog")) {
myDomain = (TopLevelTestObject)
returnTO(".class","javax.swing.JDialog");
}
else if (myDomainName.equalsIgnoreCase("javax.swing.JFrame")) {
myDomain = (TopLevelTestObject)
returnTO(".class", "javax.swing.JFrame");
}
else if (myDomainName.equalsIgnoreCase
("com.ibm.retail.rma.res.ui.config.MasterAgentInfoDlg")) {
myDomain = (TopLevelTestObject)
returnTO(".class",
"com.ibm.retail.rma.res.ui.config.MasterAgentInfoDlg");
}
/* This function returns the 1st instance of a test object based on the
* recognition property and the property value provided. If the test object
* is not found null will be returned.
*/
public TestObject returnTO(String recognitionProperty,
String recognitionPropertyValue,) {
RootTestObject rTO = getRootTestObject();
TestObject[] TOs = rTO.find(atDescendant(recognitionProperty, propValue));
TestObject returnTO = null;
int numOfObjects = TOs.length;
if (numOfObjects >= 1)
returnTO = TOs[0];
return returnTO;
} |
After the top-level test object is parsed into the correct parent test object type, use of the find() API will help in getting a reference to the child object under it. Then you can write a generic, reusable function that will work in a cross-domain manner. The code in Listing 3 is an example, where a generic setText function has been defined that will work regardless of whether the application domain is HTML, Java, or .NET or any other domain that is based on current Graphical User Interface technologies.
Listing 3. A generic cross-domain setText() function
public boolean setTextGuiTestObject(TestObject myDomain,
String recognitionProperty,
String recognitionPropertyValue,
String valueToSet) {
boolean status = true;
try {
TestObject[] TOs = null;
TOs = myDomain.find(atDescendant
(recognitionProperty, recognitionPropertyValue));
int numOfObjects = TOs.length;
if (numOfObjects >= 1) {
TextGuiTestObject myGTO1 = null;
myGTO1 = (TextGuiTestObject) TOs[0];
myGTO1.waitForExistence(2500, 0.10);
if (myGTO1.exists()) {
System.out.println("Setting Text: " + valueToSet);
myGTO1.click();
myGTO1.setText(text);
}
}
myGTO1.unregister();
}
catch (Exception e) {
System.out.println("Unable to set Text :: " + e.toString());
status = false;
}
return status;
} |
In this example, the function is not tied to any application domain. Instead, the application domain is passed as an input parameter to the function just before setting the value to Text Box. Thus, the automation script will be able to set text to edit boxes of any domain, as long as the correct domain, recognition property, property value, and the text to be set is provided.
Use this approach when application domains change often
This model of automation test script development addresses yet another aspect.
Many a times in automated testing, the application under test shifts from one domain to another. This scenario is an example:
- You started automating on an HTML, web-based application. The top-level test object in such case is: HTML.Browser.
- Midway in your script, a certain action launched an HTML dialog. With the perspective of Rational Functional Tester, the top-level test object has now shifted to HTML Dialog.
- Later, after more navigation, this browser-based application launches a Java Swing dialog, where the top-level test object has shifted to javax.swing.JDialog.
In all of these cases, if there was a common operation of setting text to the child objects under their respective top-level test objects, this approach of making the functions domain-independent will help. All you need to do is to pass a domain that is relevant to that operation. That is, first, you pass an HTML.Browser, HTML.Dialog, and then a javax.swing.JDialog. Code Listing 4 illustrates this.
Listing 4. When the top-level application domain changes often
TestObject myDomainName;
String myDomainName = "";
/*
* Step 1 - Set value to the text box in Html.Browser
*/
myDomainName = "Html.HtmlBrowser";
if (myDomainName.equalsIgnoreCase("Html.HtmlBrowser")) {
myDomain = (BrowserTestObject)returnTO(".class", "Html.HtmlBrowser");
}
setTextGuiTestObject(myDomain, ".id", "hostname", "StoreServer");
/*
* Step 2 - Set value to the text box in Html.Dialog
*/
myDomainName = "Html.Dialog";
if (myDomainName.equalsIgnoreCase("Html.Dialog")) {
myDomain = (TopLevelTestObject)returnTO(".class", "Html.Dialog");
}
setTextGuiTestObject(myDomain, ".id", "searchIP", "9.124.45.43");
/*
* Step 3 - Set value to the text box in javax.swing.JDialog
*/
myDomainName = "javax.swing.JDialog";
if (myDomainName.equalsIgnoreCase("javax.swing.JDialog ")) {
myDomain = (TopLevelTestObject)returnTO(".class", "javax.swing.JDialog");
}
setTextGuiTestObject(myDomain, ".id", "searchPort", "9443"); |
In a frequently changing application domain scenario, this approach works well. The automation scripts and functions become reusable, thus reducing redundancy.
Summary of the value of this method
You can use the method described in this article effectively in any automation tools, either commercial or open source. Making your scripts domain-independent will not simply make your scripts reusable. It will also make them robust in cases where the application functionality built in one domain, such as HTML, has been transferred to another domain, such as Java. In all cases, after you have written the test script, it can be used over multiple versions of the same product lifecycle.
Also, because the reusability of these generic functions is the result of using the cross-domain approach, the scripts and functions are not tied to a specific product nor to an application domain.
Learn
- Visit the Rational Functional Tester area on developerWorks for introductory to in-depth information.
- Explore the Rational Functional Tester Information Center, where you can also take a short video tour.
- Investigate Rational Functional Tester Plus, which is a software application testing bundle.
- Visit the Rational software area on developerWorks for technical resources and best practices for Rational Software Delivery Platform products.
- Stay current with developerWorks technical events and webcasts focused on a variety of IBM products and IT industry topics.
- Attend a free developerWorks Live! briefing to get up-to-speed quickly on IBM products and tools, as well as IT industry trends.
- Watch developerWorks on-demand demos, ranging from product installation and setup demos for beginners to advanced functionality for experienced developers.
- Improve your skills. Check the Rational training and certification catalog, which includes many types of courses on a wide range of topics. You can take some of them anywhere, any time, and many of the "Getting Started" ones are free.
Get products and technologies
- Try Rational Functional Tester free requires registration).
- Evaluate IBM software in the way that suits you best: Download it for a trial, try it online, use it in a cloud environment, or spend a few hours in the SOA Sandbox learning how to implement service-oriented architecture efficiently.
Discuss
- Get involved in the developerWorks Functional and GUI Testing discussion forum where you can discuss and ask questions about Rational Functional Tester and general testing topics.
- Rate or review Rational software. It's quick and easy.
- Share your knowledge and help others who use Rational software by writing a developerWorks article. Find out what makes a good developerWorks article and how to proceed.
- Follow Rational software on Facebook, Twitter (@ibmrational), and YouTube, and add your comments and requests.
- Ask and answer questions and increase your expertise when you get involved in the Rational forums, cafés, and wikis.
- Get social about thought leadership. Join the Rational community to share your Rational software expertise and get connected with your peers.
- Connect with others who share your interests by joining the developerWorks community and responding to the developer-driven blogs.

Shruti Grover is an Automation Consultant, and Test Lead in the Retail Software Solutions Group, IBM India Software Labs Software Technology Group. With more than 11 years of experience, she has expertise in various commercial and open-source test automation and test management tools and has led the Rational Functional Tester test team and implemented multiple test frameworks. She has made presentations on test topics at local and international conferences, including IBM Asia Pacific and Latin America Quality Software Engineering Symposiums, IBM Regional Technical Exchange, Quality Assurance Institute, Rational Software Development Conference, and TechConnect. She has also written previous developerWorks articles about Rational Functional Tester.




