Configure applications programmatically in Rational Functional Tester for a client/server test environment

A Java utility to avoid manual configuration of the application under test

While integrating IBM Rational Functional Tester with any automation framework, you must configure the application under test (AUT) properly. This includes enabling the AUT and Eclipse Graphical Editing Framework (GEF) support, setting launcher arguments of the application, and so on. Configuring these applications manually can be a bottleneck for test automation. You can use the Rational Functional Tester command line interface to automate the configuration, but only to a limited extent. By reading this article, you will learn how to use a Java utility to programmatically configure the AUT so that you can start the automated test suites from a server without any manual interference. With this automation, you can improve the integration of IBM Rational Functional Tester with any automation framework.

Share:

Amit Srivastava (amisriva@in.ibm.com), Staff Software Engineer, IBM

author photoAmit Srivastava is an IBM staff software engineer. He has been working with software test automation tools for seven years, including test automation projects using IBM Rational Robot and IBM Rational Functional Tester.



Awanish Kumar Singh (awansing@in.ibm.com), Software Engineer, IBM

author photoAwanish Kumar Singh is a software engineer at the IBM India Software Labs in Gurgaon, India. He works in the Rational Application Developer Portal Tools team and focuses on development and test automation. He is passionate about the design and development of test automation frameworks.



12 March 2013

Introduction

IBM® Rational® Functional Tester is an advanced test automation tool for performing functional and regression testing. To use the automated testing features for an application, you must first enable an environment, configure an application, and set launcher arguments of the application. You can manually perform these tasks, but doing so can be challenging and time-consuming in comparison with the automatic configuration. Also, automated configuration is a requirement for any automation framework that starts a test from a remote server. Manually configuring the application and environment has some limitations, such as manually reconfiguring Rational Functional Tester whenever there is a change in your test environment.

This manual approach can be used in single-user environments where there is a dedicated tester to perform these tasks. But it becomes excessive overhead when there are multiple testers working on a common project and using different test machines. This article explains how you can programmatically configure application in Rational Functional Tester. The Download section provides a ready-to-use Java utility to programmatically configure the application under test (AUT), enable GEF support, set launcher arguments of application and others to start automated suites from server to test machine without any manual interference.


Prerequisites

  • A general knowledge of Rational Functional Tester
  • Java programming
  • Familiarity with the Eclipse environment

Note:
IBM® Rational® Software Architect, an Eclipse-based application, is the application under test, or AUT.


Prepare the test environment programmatically

Preparing the environment involves three steps:

  1. Configure application for testing
  2. Enable environments for testing and
  3. Enable Graphical Editing Framework support

A client/server model is one that supports physically separated tester and AUT with a good network connection. In client/server test automation setup, the automation server starts the batch file (file extension: .bat). The batch job first performs the Rational Functional Tester configuration, and then it launches the test suite. The batch script performs the following tasks, in this sequence:

  1. Configure applications for testing
  2. Enable environments for testing
  3. Enable GEF support for testing an Eclipse-based application
  4. Start the test suite

See the sample code in the LaunchRFT.bat file in the Download section of this article for the batch file to run the Rational Functional Tester test suite from the command line. The batch file takes the version of the AUT as a parameter. If the version is not passed as a parameter, the test is performed on the recently installed version of the test application.

Configure application for testing

Test application configuration is required for automatic launching of test application during playback by Rational Functional Tester. When an application is configured manually, Rational Functional Tester stores its configuration information in the configurations.rftcfg file. This is the typical example of the location of this file:

%ALLUSERSPROFILE%\Application Data\IBM\Rational Functional Tester\configuration\configurations.rftcfg

After manual configuration of IBM Rational Software Architect as the application to test, the information within the tags shown in code Listing 1 is added to the configurations.rftcfg file.

Listing 1. Tags to configure the application
                <Application L=".Application">
		 <Name>eclipse</Name>
		 <Kind>executable</Kind>
		 <Path> C:\Program Files (x86)\IBM\RSA85 </Path>
		 <Command>eclipse.exe</Command>
	         <Jvm/>
		 <Classpath></Classpath>
		 <Args></Args>
		 <WorkingDir> C:\Program Files (x86)\IBM\RSA85 </WorkingDir>
	    </Application>

To achieve automatic configuration of the AUT, the nodes in Listing 1 need to be added programmatically in the configurations.rftcfg file. The main nodes for which value can vary according to the test application are Path, Args, and WorkingDir. You can use a Java utility to parse that file, and, by using some traversing logic, the value of a particular node or its attribute can be set programmatically.

The Args node, which contains the launcher argument of the test application, can be set by specifying the workspace path with -data as a launcher argument. This launcher argument can be used to launch the test application in a particular workspace during playback by Rational Functional Tester.

The value of Path and WorkingDir nodes are the test application installation path; therefore, you need the installation path of the test application for configuring these nodes. The test application used in this article, Rational Software Architect, is installed through IBM Installation Manager, which keeps installation information in an installed.xml file, which is typically located here:

%ALLUSERSPROFILE%\All Users\Application Data\IBM\InstallationManager\installed.xml

Using a Java utility, you can parse the installed.xml file, and, based on the product ID, you can check for a particular test application and get the installation path. However, if multiple versions of the same test application exist on the target machine, you can find the installation path of a particular test application based on the version of the application. Then you can set the values of Path and WorkingDir nodes in the Rational Functional Tester configurations.rftcfg file.

For other nodes, such as Name, Kind, Command, JVM, and Classpath, you can use their default values and set them programmatically.

All of these tasks are divided into separate Java methods, which are described in the subsections that follow. Listing 2 shows the constants and global variables used.

Listing 2. Constants and global variables used
public static final String NAME_CONFIGFILE_Rational Functional Tester =
 "/configurations.rftcfg";
public static final String PATH_CONFIGFILE_Rational Functional Tester = 
"C:/Documents and Settings/All Users/Application Data/IBM/Rational Functional Tester/
configuration/configurations.rftcfg";
public static final String PATH_INSTALLED_XML = "C:/Documents and Settings/
All Users/Application Data/IBM/Installation Manager/installed.xml";
// Specify back up folder path to take back up of configurations.rftcfg file
public static final String PATH_BACKUP_DIR = "C:/Documents and Settings/
All Users/Application Data/IBM/Rational Functional Tester/configuration/Backup";
// Specify the product id of the test application
public static final String KEY_APP = " com.ibm.rational.rsa.85";
public static final String KEY_Rational Functional Tester = 
"com.ibm.rational.functional.tester";
public static final String PATH_ECLIPSE_ENABLER = 
"/FunctionalTester/EclipseEnabler/plugins";
// Specify default workspace path
public static final String PREFIX_APP_WORKSPACE_PATH = 
"C:/Automation/workspace/";
private static String workspacePath;
private static String appInstallPath;
private static String rftInstallPath;

Main() method

This method calls all other methods and performs the whole automatic configuration task .

Listing 3. Main method to perform the entire configuration task
public static void main(String[] args) throws Exception {
    String buildId = null;
   if (args != null && args.length > 0)
	buildId = args[0];
	takeBackupConfigFile();
	Document rftcfg = getXMLDocument
(PATH_CONFIGFILE_Rational Functional Tester);
	if (rftcfg != null) {
	   Document installedXML = getXMLDocument(PATH_INSTALLED_XML);
	   appInstallPath = getInstallPath
(installedXML, KEY_APP, buildId);
		if (appInstallPath != null) {
		   rftInstallPath = getInstallPath(installedXML, 
KEY_Rational Functional Tester, "");
		   configureApplicationForTesting(rftcfg);
		   enableEnvironmentForTesting(rftcfg);
		   enableGEFSupport( new File
(appInstallPath + "/" + "plugins"),new  
                   File(rftInstallPath +   PATH_ECLIPSE_ENABLER));
		  }
	}
}

takeBackupConfigFile() method

This method makes a backup of the configurations.rftcfg file before making any change to the file.

Listing 4. Make a backup of the configurations.rftcfg file
private static void takeBackupConfigFile() throws IOException {
    File backupFolder = new File(PATH_BACKUP_DIR);
    backupFolder.mkdir();
	  if (backupFolder.exists()) {
	       if (!backupFolder.isDirectory())
				backupFolder.mkdir();
	    } else
	        backupFolder.createNewFile();
		File backupFile = new File(PATH_BACKUP_DIR +
NAME_CONFIGFILE_Rational Functional Tester);
		if (!backupFile.exists()) {
		     copyContent(backupFile, new File
(PATH_CONFIGFILE_Rational Functional Tester));
	    }
     }

getXMLDocument() method

This method, shown in Listing 5, gets an XML document by passing the XML file location.

Listing 5. Get an XML document
private static Document getXMLDocument(String xmlfilelocation) {
    Document document = null;
    DocumentBuilder db = null;
    try {
           DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
           dbfactory.setIgnoringElementContentWhitespace(true);
           db = dbfactory.newDocumentBuilder();
           document = db.parse(new File(xmlfilelocation));
	    document.getDocumentElement().normalize();
	  } catch (Exception e) {
		    e.printStackTrace();
	   }
	return document;
    }

configureApplicationForTesting() method

This method is about adding nodes for the test application in the Rational Functional Tester configurations.rftcfg file.

Listing 6. Configure the test application in the configurations.rftcfg file

Click to see code listing

Listing 6. Configure the test application in the configurations.rftcfg file

public static void configureApplicationForTesting(Document document) {addNodeToParent(document, "ApplicationList", "Application", false);
    addNodeToParent(document, "Application", "Name", true);
    addNodeToParent(document, "Application", "Kind", true);
    addNodeToParent(document, "Application", "Path", true);
    addNodeToParent(document, "Application", "Command", true);
    addNodeToParent(document, "Application", "Jvm", true);
    addNodeToParent(document, "Application", "Classpath", true);
    addNodeToParent(document, "Application", "Args", true);
    addNodeToParent(document, "Application", "WorkingDir", true);
 }

addNodeToParent () method

This one is about adding child node to a parent node by taking the parent node name as a parameter.

Listing 7. Add a child node to a given parent node
privatestaticvoid addNodeToParent(Document document, String parentName,
  String nodeName, boolean isTextNodeRequire) {
    NodeList nodelist = document.getElementsByTagName(parentName);
    if (nodelist != null && nodelist.getLength() > 0) {
    Node parentNode = nodelist.item(0);
    Element parentElement = (Element) parentNode;
    Element element = document.createElement(nodeName);
    NodeList childNodelist = parentElement.getElementsByTagName(nodeName);
    Element childElement = (Element) childNodelist.item(0);
    String value = getAttributeValue(nodeName);
        if (childElement == null) {
	   parentElement.appendChild(element);
	   if (nodeName == ("Application"))
	      element.setAttributeNS(null, "L", ".Application");
	      if (nodeName == ("EclipseShell"))
		  element.setAttributeNS(null, "L", ".EclipseShell");
		  if (isTextNodeRequire) {
			    Node textNode = document.createTextNode("data");
			    element.appendChild(textNode);
			    textNode.setNodeValue(value);
		   }
	   } else {
	     if (nodeName == ("Application"))
		childElement.setAttributeNS(null, "L", ".Application");
		    if (nodeName == ("EclipseShell"))
			childElement.setAttributeNS(null, "L", ".EclipseShell");
			NodeList textNodeList = childElement.getChildNodes();
			Node node = (Node) textNodeList.item(0);
			if (node == null && isTextNodeRequire) {
			    Node textnode = document.createTextNode("data");
			    textnode.setNodeValue(value);
			    childElement.appendChild(textnode);
			} else {
			   node.setNodeValue(value);
			}
		}
	}
		updateRational Functional TesterConfigFile(document);
}

updateRFTConfigFile () method

As shown in Listing 8, it updates Rational Functional Tester configuration file (configurations.rftcfg ) when changes are performed in the document object for test application configuration and test environment configuration.

Listing 8. Update the Rational Functional Tester configuration file
private static void updateRational Functional TesterConfigFile(Document doc) {
    Transformer transformer = null;
    try {
	 transformer = TransformerFactory.newInstance().newTransformer();
	 StreamResult result = new StreamResult(new StringWriter());
	 DOMSource source = new DOMSource(doc);
	 transformer.transform(source, result);
	 String finalOutput = result.getWriter().toString();
	 BufferedWriter out;
	 File configFile = new File(PATH_CONFIGFILE_Rational Functional Tester);
	 if (configFile.exists())
		 configFile.delete();
		 out = new BufferedWriter(new FileWriter
(PATH_CONFIGFILE_Rational Functional Tester, true));
		 out.write(finalOutput);
		 out.close();
	  } catch (Exception e) {
		e.printStackTrace();
	 }
}

getNodesWithXPath () method

This is used to get the NodeList by passing XPath as parameter.

Listing 9. Get NodeList with XPath
private static NodeList getNodesWithXPath(Document document, String xpathStr)
 throws XPathExpressionException {
    NodeList nodes = null;
    XPathFactory factory = XPathFactory.newInstance();
    XPath xpath = factory.newXPath();
    if (xpathStr != null) {
    XPathExpression expr = xpath.compile(xpathStr);
    Object result = expr.evaluate(document, XPathConstants.NODESET);
    nodes = (NodeList) result;
	}
    return nodes;
}

generateWorkspaceName () method

This method generates a unique workspace name, using the current date.

Listing 10. Generate a unique workspace name
privatestatic String generateWorkspaceName() {
    DateFormat dateformat = new SimpleDateFormat("yyyyMMdd_HHmmss");
    Date date = new Date();
    String lastPart = dateformat.format(date);
    workspacePath = PREFIX_APP_WORKSPACE_PATH + lastPart;
    return workspacePath;
}

getInstallPath() method

As Listing 11 shows, this method finds the installation path of the test application. It can also be used to get the installation path of Rational Functional Tester. It takes the installed.XML document object, test application product ID, and test application build ID as parameters.

Listing 11. Get the installation path of the test application
private static String getInstallPath(Document document, String key,
 String buildId) throws Exception {
    String latestAppPath = null;
    NodeList nodes = getNodesWithXPath(document, "//package[@id='" + key + "']");
    if (buildId.equalsIgnoreCase("")) {
	Node pakage = nodes.item(nodes.getLength() - 1);
	Element location = (Element) pakage.getParentNode();
	if (location.hasAttribute("path")) {
	     latestAppPath = location.getAttribute("path").replace("\\", "/");
	     }
	 } else {
	     for (int i = 0; i < nodes.getLength(); i++) {
		 Node packNode = nodes.item(i);
		 Element packElement = (Element) nodes.item(i);
		 if (packElement.hasAttribute("version")) {
	         String id = packElement.getAttribute("version").toString();
		     if (id.contains(buildId)) {
			 Element location = (Element) packNode.getParentNode();
			latestAppPath = location.getAttribute("path").replace("\\", "/");
			 break;
			  }
		     }
		 }
	       if (latestAppPath == null) {
	           throw new Exception("Application with given build ID " + buildId
				+ " not found");
			}
		}
	return latestAppPath;
}

getAttributeValue () method

This is used to get the value of a particular attribute.

Listing 12. Get the attribute's value
privatestatic String getAttributeValue(String attribute) {
    String attrValue = "";
	if (attribute.equalsIgnoreCase("Name"))
	     attrValue = "eclipse";
	if (attribute.equalsIgnoreCase("Kind"))
	     attrValue = "executable";
	if (attribute.equalsIgnoreCase("Path"))
	     attrValue = appInstallPath;
	if (attribute.equalsIgnoreCase("Command"))
	     attrValue = "eclipse.exe";
	if (attribute.equalsIgnoreCase("Args"))
	     attrValue = "-data " + generateWorkspaceName();
	if (attribute.equalsIgnoreCase("WorkingDir"))
	     attrValue = appInstallPath;
   return attrValue;
}

Enable environments for testing

To use the script recording and playback features of Rational Functional Tester, you must enable the environment for testing. For this article, we used IBM Rational Software Architect (an Eclipse-based application) as the application under test. Thus, to enable Eclipse as a test environment, the following tags need to be added to the Rational Functional Tester configurations.rftcfg file:

Listing 13. Tags to enable Eclipse as a test environment
         <EclipseShell L=".EclipseShell">
		<Name>eclipse</Name>
		<Path>C:/Program Files (x86)/IBM/SDP851</Path>
	  </EclipseShell>

For automatic enablement of the test environment, the approach for configuring applications for testing can be used here, as well. The value of the Path node is the installation path of the test application. You can get it with code in Listing 11. For node name, you can go with the default value.

The enableEnvironmentForTesting() Java function shown in Listing 14 adds nodes in the configurations.rftcfg file for enabling a test environment.

Listing 14. Sample code to enable Test environment

Click to see code listing

Listing 14. Sample code to enable Test environment

public static void enableEnvironmentForTesting(Document document){addNodeToParent(document, "EclipseShellList", "EclipseShell", false);
		addNodeToParent(document, "EclipseShell", "Name", true);
		addNodeToParent(document, "EclipseShell", "Path", true);
	}

Enable Graphical Editing Framework support

By using Rational Functional Tester, you can test the functionality of Graphical Editing Framework (GEF) objects. You can perform data, image or properties verification on the GEF objects, because Rational Functional Tester recognizes the GEF EditParts and Palettes. To use this feature, you must enable the GEF applications for testing before recording the functional test scripts. If the GEF application is not enabled for testing, Rational Functional Tester recognizes GEF objects as FigureCanvas. When you manually enable GEF support, the GEF enablement plug-in is copied to the plug-in the directory of the AUT. In the Java code in Listing 3, we are performing the same task programmatically. The Java code in Listing 15 displays functions for enabling GEF support.

Listing 15. Java code to enable GEF support
public static void enableGEFSupport(File destDir, File sourceDir) throws IOException {
    if (sourceDir != null && sourceDir.isDirectory()) {
	if (destDir != null && !destDir.exists()) {
		destDir.mkdir();
		}
	File[] files = sourceDir.listFiles();
	for (File file : files) {
	enableGEFSupport(new File(destDir, file.getName()), new File(
		sourceDir, file.getName()));
		}
     } else {
	      copyContent(destDir, sourceDir);
	}
}

The copyContent() method shown in Listing 16 copies the content of one folder to another folder.

Listing 16. Copy content from one folder to another folder
private static void copyContent(File destDir, File sourceDir) throws IOException {
    InputStream input;
    input = new FileInputStream(sourceDir);
    OutputStream output = new FileOutputStream(destDir);
    byte[] buffer = new byte[4096];
    int length;
    while ((length = input.read(buffer)) > 0) {
    output.write(buffer, 0, length);
    }
    input.close();
    output.close();
}

ConfigureRFT.java, the complete Java utility to programmatically configure the AUT, contains all of the preceding methods. It is available in the Download section of this article.


Summary

This article explains how to automatically configure Rational Functional Tester in a client/server test environment by modifying the configuration file. With this automation, you can improve the integration of IBM Rational Functional Tester with any automation framework.


Download

DescriptionNameSize
Batch file and Java utilityconfigure-applications-programmatically.zip5KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Rational software on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational
ArticleID=860854
ArticleTitle=Configure applications programmatically in Rational Functional Tester for a client/server test environment
publish-date=03122013