Control loops - Trade example

 

+

Search Tips   |   Advanced Search

 

This example demonstrates extending test execution by using custom code to control loops.

This example uses a recording of a stock purchase transaction using IBM's Trade application. The test begins with a recording of a stock purchase transaction, using datapool substitution for the login IDs.

The pages are wrapped in a five-iteration loop...

The first piece of custom code, InitializeBuyTest, contains...

// InitializeBuyTest

package test;

import java.util.Random;

import com.ibm.rational.test.lt.kernel.IDataArea;
import com.ibm.rational.test.lt.kernel.services.ITestExecutionServices;
import com.ibm.rational.test.lt.kernel.services.IVirtualUserInfo;

public class InitializeBuyTest implements
    com.ibm.rational.test.lt.kernel.custom.ICustomCode2 
{
  // Instances created using the no-arg constructor.

  public InitializeBuyTest() 
  {
  }

  public String exec(ITestExecutionServices tes, String[] args) 
  {
    // Get the test's data area and set a flag indicating that nothing
    // has failed yet. This flag will be used later to break out
    // of the schedule loop as soon as a failure is encountered.

    IDataArea dataArea = tes.findDataArea(IDataArea.TEST);
    dataArea.put("failedYet", "false");

    // Get the virtual users's data area
    IDataArea vda = tes.findDataArea(IDataArea.VIRTUALUSER);
    
    // Randomly select a stock to purchase from the set of s:0 to s:499.

    IVirtualUserInfo vuInfo = (IVirtualUserInfo) vda.get(IVirtualUserInfo.KEY);
    Random rand = vuInfo.getRandom();
    String stock = "s:" + Integer.toString(rand.nextInt(499));

    // Persist the name of the stock in the virtual user's data area.
    vda.put("myStock", stock);

    return stock;
  }
}

First, the data area for the test is acquired to store a flag value, in this case a string of text, to be used later to stop the test loop when an error is discovered. Data stored in this way can be persisted across tests.

Then a randomly generated stock string is created. The value is stored as the variable stock, and is passed back as the return value for the method. This return value is used as a substitute in a request later...

The highlighted item uses a substitution (s%3A716), which is the value returned by the InitializeBuyTest custom code item. We are using custom code to drive the direction of our test.

The next lines of code in InitializeBuyTest use the Virtual User data area to store the name of the stock for later reference. Again, data stored in this way can persist across tests.

The second piece of custom code is called CheckStock. Its contents are as follows (listing only the exec() method this time):

public String exec(ITestExecutionServices tes, String[] args) 
{

    // Get the actual and requested stock purchased.
    String actualStock = args[0].replaceAll("<B>", "");

    actualStock = actualStock.substring(0, actualStock.indexOf("<"));

    String requestedStock = args[1];

    // Set the log level to ALL.
    IDataArea dataArea = tes.findDataArea(IDataArea.TEST);
    ITestInfo testInfo = (ITestInfo)dataArea.get(ITestInfo.KEY);
    testInfo.setTestLogLevel(ITestLogManager.ALL);

    // If the log level is set to ALL, report the actual and requested stock
    // purchased.

    ITestLogManager testLogManager = tes.getTestLogManager();


    if (testLogManager.wouldReport(ITestLogManager.ALL)) 
              
    {
       testLogManager.reportMessage("Actual stock purchased: "
                                   + actualStock + ". Requested stock: " + requestedStock
                                   + ".");
    }      

    // If the actual and requested stock don't match, submit a FAIL verdict.
    if (testLogManager.wouldReport(ITestLogManager.ALL)) 
    { 
      if (!actualStock.equalsIgnoreCase(requestedStock)) 
      {
          testLogManager.reportVerdict("Actual and requested purchase stock do not match.",
                                        VerdictEvent.VERDICT_FAIL);

        // Use the test's data area to record the fact that an error has occurred.
        dataArea.put("failedYet", "true");
      }     
    }

    return null;
}

This code begins by extracting two arguments that have been passed to the code. A part of the response in the original recording is highlighted and used as a reference...

Some string manipulation is needed to acquire the text of interest; in this case, the name of the stock that was actually purchased. This newly created reference is then passed into CheckStock as an argument...

Note that the return value of InitializeBuyTest is passed in as an argument as well.

The CheckStock custom code item uses these values to verify that the randomly chosen stock generated by InitializeBuyTest is actually purchased during the execution of the test.

CheckStock then sets the test log level, reports the actual and requested stock purchase, and raises a FAIL verdict if they do not match. CheckStock also stores a true value associated with the tag failedYet in the test's data area.

The third piece of custom code uses the test's data area to determine the user-defined value associated with the tag failedYet. If true, StopLoopCheck breaks out of the test loop.

package test;

import com.ibm.rational.test.lt.kernel.IDataArea;
import com.ibm.rational.test.lt.kernel.services.ITestExecutionServices;
import com.ibm.rational.test.lt.kernel.services.ITestLogManager;

public class StopLoopCheck implements
    com.ibm.rational.test.lt.kernel.custom.ICustomCode2 {

  /**
   * Create using no-arg constructor.
   */
  public StopLoopCheck() {
  }

  public String exec(ITestExecutionServices tes, String[] args) 
  {

      // Get the test log manager.
      ITestLogManager testLogManager = tes.getTestLogManager();
      
      // Get the test's data area and get a flag indicating to
      // see if anything has failed yet. If so, stop the loop.
      IDataArea dataArea = tes.findDataArea(IDataArea.TEST);
      String failedYet = (String) dataArea.get("failedYet");

      // Break out of the loop if an error has been encountered.
      if (failedYet.equalsIgnoreCase("true")) 
      {
        tes.getLoopControl().breakLoop();

        if (testLogManager.wouldReport(ITestLogManager.ALL)) 
        {
          testLogManager.reportMessage("Loop stopped.");
        }
      }

      return null;
  }
    }
}