JETPack - Java Enabled TET Package

Java Enabled TETware is a language binding for the Test Environment Toolkit. This language bindings permits the development of tests in the Java programming language, and also permits the development of tests that exercise existing Java-language classes and methods.

Below you will find a brief overview of JETPack and an example of its use. For detailed documentation on the JETPack API, see the javadoc generated documentation for the TestSession interface. If you are interested in doing multi-threaded testing under JETPack, have a look at the TetThread class documentation. If you are thinking of writing your own TestCase driver, see the javadoc generated documentation for the TestCase interface. In many cases, the JETpack methods have names similar to those in TETware's C language API. In those cases, the authoritative documentation on the method's semantics can be found in the TETware documentation.

JETPack Philosophy

JETpack is implemented as a Java binding that relies upon the TET API libraries. These libraries are bound to the executing Java Byte Code engine using the Java Native Interface - the JavaSoft standard method for accessing native code from a Java application.

The philosophy of this interface is that the Java application should drive the test. This is somewhat at odds with the general TET philosophy that the TET test case manager should be the "main" for the test case. However, we felt that the Java community would be more likely to embrace a test scaffold that was implemented from the Java perspective.

This does not mean that user-provided code is needed to drive the tests. On the contrary, the test drivers are much as they are in TET's C and C++ language bindings. Users write test routines as methods of a test class, and the test driver calls these test routines after establishing the appropriate protected environment. However, the entry point for the test is a user-provided main() in the user's class under test. This main() needs to instantiate the TET test class and call the TET test driver. This means that the user can perform any needed setup or cleanup code around the call to the TET test driver.

We have adopted this philosophy because we envision a broad variety of uses for JETpack, and also because we expect that someday the entire JETpack will be implemented in 100% Java, and not rely upon any native code at all. By taking this approach, tests developed using this version of JETpack should be compatible with any such future implementation of JETpack.

Using JETPack

JETPack comes with a gross test control method defined in the TET.TestCase interface. An implementation of this interface is the SimpleTestCase class. It permits the development of tests with an arbitrary number of test purposes per invocable component, and an arbitrary number of invocable components per test case. This class should be adequate for most uses. For more advanced uses of TET, the user can create their own implementation of the TestCase interface that implements their own rules.

The SimpleTestCase class provides a foundation upon which user test cases may be based. One begins a new test case by making it a subclass of SimpleTestCase:

  public class NewTestCase extends TET.SimpleTestCase {
    //...
  }
In addition, the new test case class must provide a static main() procedure which creates an instance of the test case class and passes control back to JET's test case manager:
    public static void main (String args[]) {
      main("NewTestCaseName", args, new NewTestCase());
    }
The first argument is the name of the test case, i.e. what calling tet_pname() should return.

Test purposes are defined by creating public instance methods whose names are of the form: i#t# where each pound sign ("#") represents a sequence of one or more digits. The first sequence of digits (the "i"-string) denotes the number of the invocable component to which the test purpose belongs; the second sequence (the "t"-string) is used to determine the execution order of the test purposes. The "i"-string must evaluate to an integer greater than zero (which is taken to be the invocable component number). There are no restrictions on the digits in the "t"-string.

The test purpose methods should return "void" and take a single argument of class TET.TestSession. Some JET routines throw exceptions, and test purposes which make use of them should either catch the exception or declare it in a throws clause. Uncaught TetExceptions thrown from within test purposes will result in recording of the exception to the results file and termination of the current test purpose.

Some examples of test purpose declarations are:

    public void i1t1(TET.TestSession ts) { }
    public void i2t1(TET.TestSession ts) throws TET.TetException { }
    public void t2(TET.TestSession ts) { }
    // ...
As a short cut, test purpose methods may be abbreviated to "t#" in which case they are assumed to belong to invocable component number 1.

Within an invocable component test purposes are executed based on the lexigraphical ordering of their "t"-strings. Thus "t0" will be executed before "t00". The test purpose id assigned to a test purpose will be its rank in this lexigraphical ordering (starting at 1). In the event that two test purposes have the same "t"-strings, the order in which they are executed is indeterminate. (This can only happen if abbreviated test purpose names are used.)

Using a TestSession within a test purpose

When a test purpose is invoked it is passed an object which conforms to the interface TET.TestSession. In general this will be an instance of TET.JetTestSession.

Currently JetTestSession supplies the following TET functionality:

Basic (TET_LITE) interfaces:

  public void tet_infoline(String line);
  public void tet_minfoline(String lines[]) throws TetException;
  public String tet_pname();
  public int tet_thistest();
  public String tet_getvar(String name);
  public void tet_setcontext();
  public void tet_setblock();
  public int tet_getblock();
  public void tet_delete(int tp, String reason);
  public String tet_reason(int tp);
  public void tet_result(int result);
TETware/TET3 interfaces (available when built in inet mode):
  public void tet_exit(int status) throws TetException;
  public void tet_logoff();
  public native int tet_remgetsys() throws TetException;
  public int[] tet_remgetlist() throws TetException;
  public SystemEntry tet_getsysbyid(int sysid) throws TetException;
  public java.util.Date tet_remtime(int sysid) throws TetException;
  public void tet_remsync(long syncptno, int sysnames[], int waittime, int vote,
 SyncMessage msg) throws TetException;
All of these methods behave just like their C-API counterparts. See the TET3/TETware C binding documentation for their semantic definitions.

The exception TetException is thrown if the version of TETware installed on the platform is not built to support remote/distributed testing.

The result constants for tet_result() (such as TET_PASS, TET_FAIL, etc.) may be accessed from the TestSession object itself (ts.TET_PASS, ts.TET_FAIL, etc. where ts is the TestSession object.)