IBM Support

Building and Unit Testing Custom Functions within RIT

Question & Answer


Question

How do you build and Unit Test IBM Rational Integration Tester (RIT) custom functions using Ant, the Java SDK, and RIT?

Answer

Introduction

Most custom functions are built with Eclipse as described in the Quick instructions for RIT Custom Function in Eclipse and in the Product Manual which also details how to create a custom function without Eclipse by using the command line tools from the Java SDK.

This document explains how to build the custom function using Apache Ant instead. This is arguably easier than using the Java SDK command line tools alone, but has the same advantages of reproducibility. It is also an approach which fits well with continuous integration tools such as Jenkins.

The document also explains how Unit Tests can then be built in RIT. Building such tests in Eclipse using JUnit is problematic since the required platform is difficult to set up and tear down. Instead developing these Unit Tests in IBM Rational Integration Tester (RIT) avoids the require platform is already in place.

Combining the Ant build with our RIT Project aims to minimise the time taken for each build and test cycle. The document then shows how to combine these advantages whilst continuing to edit the Java source code from the Eclipse environment to take advantages of the code completion, validation and refactoring features which that environment provides.

The anatomy of a custom function

A custom function is an deployed in a JAR file. A JAR file is an archive which contains other files. Each contained file has an internal path. The format of a JAR file makes it an instance of a ZIP file which can be opened and viewed with ZIP file viewers such as 7-zip.

Inside our JAR file there need to be a minimum of three items:

  • A file META-INF/MANIFEST.MF
  • A file plugin.xml
  • The class files which are created when the Java source code of your custom functions is compiled.
  • and optionally any resource files which are used by your Java classes.

It is simple to hand code the plugin.xml file, but the format of the MANIFEST.MF file is intricate. Fortunately Ant can create the MANIFEST.MF file for us whilst adding the other entries to the JAR.

    Question: Why are RIT Custom Functions structured this way?
    Answer: RIT is an example of an OSGi Product and so everything is an OSGi module, and the above is a structure of an OSGi module. OSGi simplifies the creation of large software systems because the only access to the OSGi module accessible from other OSGi modules are those entry points declared in the OSGi module interface.

The tools required

You will need:


For each you must set up some environment variables, see below.

Environment variables

These environment variables must be created:

  • JAVA_HOME needs to be pointed to the base location of the Java SDK.
  • ANT_HOME needs to be pointed to the base location of the Ant install.
  • RIT_GHTESTER_JAR needs to point to the available GHTester JAR file which is part of RIT.

For example once these environment variables are set we may check them:


The JAVA_HOME variable allows Ant to locate the Java SDK. The ANT_HOME variable allows RIT to locate and launch Ant. The RIT_GHTESTER_JAR variable allows Ant to put the required library on the Java class path so that your Java custom functions (which extend the class com.ghc.ghTester.expressions.Function) can be compiled.

Example Custom Functions

For the purposes of this custom function we will use two sample custom functions defined in these classes:

  • com.ibm.example.Base64Decode
  • com.ibm.example.Base64Encode

These custom functions are very simple. Base64Encode turns any string into a base 64 encoded string. Base64Decode turns any base 64 encoded string back into corresponding original string.


    e.g.

    Base64Encode( "my data" ) yields bXkgZGF0YQ==

    Base64Decode( "bXkgZGF0YQ==" ) yields my data


The source code to these functions can be seen in the attached RIT project.

The plugin.xml file

This file "plugin.xml" can be found in the root of the sample project.


For each additional custom function another function node would need to be added with the same set of attributes. These are the same parameters as described on the manual page "configuring the extension point element".

The Ant build script build.xml

This file "build.xml" can be found in the root of the sample project.


This is the Ant build file. When Ant is invoked it will read this file and use the definitions in the build file to compile the specified target. The default target "all" is given as an attribute in the project root node. The "all" target node causes the other targets "clean", "compile" and "jar" to be invoked in turn.

The targets are all driven by the property node name - value pairs at the top of the file. It is unlikely that any aspect of the build file other than those property values will ever need to be modified.

The "clean" target deletes files created in the previous build. The "compile" target attempts to compile all Java source code in the source code folder "src" which is found in the same location as build.xml (which is the root folder of the RIT project). The "jar" target creates the custom function JAR file by using the definitions in the manifest node and copies in the compiled version of the Java classes and the plugin.xml file.


    If using this as a template for your own custom functions you only need change the value attributes in these lines:
    <property name="jar.filename" value="ExampleCustomFunctions" />
    <property name="jar.vendor" value="IBM Rational Integration Tester Support" />

    You may also wish to change the java.version value.


The documentation for each node used in the above ant build file can be found in the Ant Manual. The reference material can be found in the manual sections "Ant Tasks" and "Concepts and Tasks".

Running the build from within RIT

Since the location of Ant is given in the ANT_HOME environment variable, and the build.xml file is located in the root of the RIT project, the Ant build can be invoked using a Function Action like this:


    pushd
    cd "%%PROJECT/ROOT_DIRECTORY%%
    %ANT_HOME%\bin\ant -f build.xml
    popd

(The only change to the above needed for Unix or Linux would be to change the path separator from \ to / ).

We should also use the Function Action features to capture the standard out and standard error and log these to the RIT console, and to capture the exit code and Assert that it is zero. The sample project contains a build test which does this and then prompts the user to reload the custom functions. (It also contains a test to launch Windows Explorer in the project root folder.)

Before we can use or unit test the newly compiled custom functions we must tell RIT to load the new version of the custom functions. This is done by selecting menus "Tools", "Functions", "Reload Custom Functions / Behaviours".

Building a Unit Test within RIT

RIT is designed to implement Integration tests but there is nothing preventing the same mechanism being used to define unit tests. A unit test typically contains just a single Assert Action using ECMAScript to invoke the custom function and then validate that the returned value is as expected. (The value returned from an ECMAScript is the value of the last expression evaluated in the script.)

For example we can code a simple unit test of our Base64Decode custom function with an Assert Action like this:


This and similar unit tests can be found in the attached project.

It is nice to put all the unit tests into a test suite so that they can be invoked as a batch after each compile.

Putting it all together

This is how it should look when we run our build from inside RIT then reload the custom functions and run our suite of unit tests.


Using Eclipse for the Java code development

Whilst compiling the custom functions from within RIT using ANT is good for making the build of the custom functions repeatable, and for ensuring the quality of the custom functions through the use of unit testing, there are many features available within Java development environments like Eclipse which would be missing if the Java code were simply created in a text editor.

One way to make the code maintainable in Eclipse is to follow this solution:

  • Create a new Java Project in Eclipse.
  • Delete the "src" folder generated as part of the project.
  • Right click the new project and select "Build Path", "Link Source"
  • Click "Browse" and select the "src" folder in the RIT project.
  • Enter "src" as the name for the folder name and click "Finish".

It should now be possible to add maintain and delete source code in the RIT "src" folder from the Eclipse application.

Since many of the features of the Eclipse environment require that Eclipse can compile the code the GH Tester JAR will need to be added to the build path of the Java Project.. The simplest way to do this is:

  • Right click the new project and select "Build Path", "Configure Build Path"
  • On the "Libraries" tab click "Add External Jars"
  • Browse to and add the GHTester JAR, e.g.
    C:/Program Files (x86)/IBM/IMShared/plugins/com.ghc.ghTester_1.860.3.v20141216_1619.jar

This will allow you to use many Eclipse features such as code completion and refactoring. It will not however allow you to execute (and hence not allow you to debug) any code containing a reference to the com.ghc.ghTester.expressions package. For this reason it remains sensible to code any complex functions in their own unit and simply call this from the custom function class.

The sample project

Here is a sample project. It requires that Ant and the Java SDK are installed, and that the environment variables are set as above. The sample project runs on Windows but the changes to run it on Linux or Unix should be trivial since the bulk of the process is driven by either Ant or RIT.

AntCustomFunction.zipAntCustomFunction.zip

[{"Product":{"code":"SSBLQQ","label":"IBM Rational Test Workbench"},"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Component":"Rational Integration Tester","Platform":[{"code":"PF002","label":"AIX"},{"code":"PF016","label":"Linux"},{"code":"PF022","label":"OS X"},{"code":"PF027","label":"Solaris"},{"code":"PF033","label":"Windows"}],"Version":"8.0;8.5;8.6","Edition":"All Editions","Line of Business":{"code":"LOB45","label":"Automation"}}]

Document Information

Modified date:
11 July 2019

UID

swg21696246