2 OpenScript Scripting Basics

This chapter explains the procedures for creating and modifying scripts in the OpenScript code view.

2.1 About Oracle OpenScript

OpenScript APIs are used to build scripts for testing Web applications. The OpenScript API consists of a set of procedures that can be used to customize the scripts within the development environment. The API can also be used by advanced technical users to enhance scripts for unique testing needs.

2.2 Starting the OpenScript Workbench

To start the OpenScript workbench:

From the Start menu:

  • Select Programs from the Start menu and then select OpenScript from the Oracle Application Testing Suite menu.

2.3 Overview of the OpenScript Main Window (Workbench)

The OpenScript main window (Workbench) is where you perform the majority of your test development activities. The main window consists of the perspectives used for developing scripts. OpenScript includes a Tester Perspective and a Developer Perspective. The menu bar, toolbar, and the views and editors vary depending upon which perspective is being used. The following sections describe the functionality and various elements of the OpenScript Workbench.

Some dialogs and views require the user to hit the popup menu keyboard button in order to access some features in the UI that are normally accessible using the right-click menu.

2.3.1 Tester Perspective

The OpenScript Tester Perspective provides a convenient way to record and edit scripts and view the playback results. The Tester Perspective opens the following views by default. The Assets view tab shows the script assets (databanks, jar files, Object libraries and child scripts) that have been added to the script.

  • Script View: Shows the recorded script in two tabs: Tree View and Java Code. The Tree View tab shows the steps and pages and the Initialize, Run, and Finish nodes of each step using a graphical tree view. The Java Code tab shows the underlying Java code used for the script.

  • Details View: Shows the content details for URL navigations or pages added to the script.

  • Problems View: Shows any problems in the script code that may produce errors or prevent compiling the script.

  • Properties View: Shows the properties for the selected node in the script.

  • Console View: Shows the playback command output and status information for the script. Script log message also appear in the Console.

  • Results View: Shows the results of script playback.

The following views are also available from the View menu but do not open by default:

  • Error Log View: Shows the error log information for the project and script.

  • Data Table View: Shows a spreadsheet-like data table for Functional testing scripts.

  • Object Details View: Shows the attributes and values for the object selected in the browser connected to the view.

  • Script Variables View: Shows the name and value of script variables. The script variables are only shown when a running script is paused during playback.

  • Treeview Breakpoint View: Shows the location of breakpoints set in the script tree view.

2.3.2 Developer Perspective

The OpenScript Developer Perspective provides advanced options for developers when creating and editing scripts using the advanced features of OpenScript and the Eclipse development platform. The Developer Perspective opens the following views by default:

  • Navigator and Package Explorer Views: Shows hierarchical views of the script project resources. You can open the resource files in an editor to view and edit the contents.

  • Script View: Shows the recorded script in two tabs: Tree View and Java Code. The Tree View tab shows the steps and pages and the Initialize, Run, and Finish nodes of each step using a graphical tree view. The Java Code tab shows the underlying Java code used for the script. The Assets view tab shows the script assets (databanks, jar files, Object libraries and child scripts) that have been added to the script. 

  • Debug View: Shows the debugging options and provides options for stepping through code.

  • Variables and Breakpoint Views: Shows the script variables and breakpoints set in the code.

  • Problems View: Shows any problems in the script code that may produce errors or prevent compiling the script.

  • Declaration View: shows the source of the element selected in the Java code view.

The following views are also available but do not open by default:

  • Details View: Shows recorded page details in three tabs: HTML, Browser, and Header. The HTML tab shows the page HTML source. The Browser tab shows the page. The Header tab shows the page response header.

  • Properties View: Shows the properties for the selected node in the script.

  • Console View: Shows the playback command output and status information for the script. Script log message also appear in the Console.

  • Results View: Shows the results of script playback.

  • Error Log View: Shows the error log information for the project and script.

  • Data Table View: Shows a spreadsheet-like data table for Functional testing scripts.

  • Object Details View: Shows the attributes and values for the object selected in the browser connected to the view.

  • Script Variables View: Shows the name and value of script variables. The script variables are only shown when a running script is paused during playback.

  • Treeview Breakpoint View: Shows the location of breakpoints set in the script tree view.

The views are described in more detail in the following sections.

2.3.3 Script View

Shows the recorded script in two tabs: Tree View and Java Code. The Tree View tab shows the steps and pages and the Initialize, Run, and Finish nodes of each step using a graphical tree view. The Java Code tab shows the underlying Java code used for the script.

The script view is where you perform the majority of script editing actions. The Script view has the following tab views:

2.3.3.1 Tree View

The Tree View shows the script navigations and data as nodes in a collapsible tree view. The Tree View corresponds to the Java Code view. Any changes in the Tree View will be automatically updated in the Java Code view. The Tree View has the following standard nodes:

  • Initialize - specifies script actions to perform once at the beginning of script playback.

  • Run - specifies script actions to perform one or more times during script playback depending upon databanks or other custom programming.

  • Finish - specifies script actions to perform once at the end of script playback.

Use the Record options and right-click shortcut menu to add options to script nodes or modify the properties of script nodes in the Tree View.

2.3.3.2 Java Code

The Java Code view shows the script navigations and data as Java programming code. The Java Code view corresponds to the Tree View. Any changes in the Code View will be automatically updated in the Tree View. The Java Code view has the following standard procedures:

  • initialize() - corresponds to the Initialize node of the Tree View and executes any custom code added once at the beginning of script playback.

  • run() - corresponds to the Run node of the Tree View and executes recorded and custom code one or more times during script playback depending upon databanks or other custom programming.

  • finish() - corresponds to the Finish node of the Tree View and executes any custom code added once at the end of script playback.

Use Ctrl-space to open an Intellisense window listing available procedures. See the API Reference in the OpenScript Platform Reference help for additional programming information.

2.3.3.3 Assets

The Assets view tab shows the script assets (databanks, jar files, Object libraries and child scripts) that have been added to the script. If assets have been added to a script, the tree shows a plus/minus next to the asset name for expanding or collapsing the asset tree. The Assets tab has the following options:

  • Databanks: Lists the Databank assets added to a script.

  • Object Libraries: Lists the Object Library assets added to a script.

  • JAR files: Lists generic JAR file assets added to a script.

  • Script: Lists the child script assets added to a script.

  • Add: Opens a file selection dialog box for selecting the file to add as an asset. Expand the My Repositories tree to navigate to a workspace folder containing the file. For Databanks, a submenu opens for selecting CSV file or database-type databanks. For CSV file databanks, you select the file. For database-type databanks, you specify the database driver and connection information.

    Note:

    Any scripts you plan to run, along with any associated assets, in the Oracle Load Testing application must be stored in a repository/workspace that can be accessed by the Oracle Load Testing Controller. If you create new repositories in OpenScript, you should also add the new repositories in Oracle Load Testing.
  • Edit: Opens a file selection dialog box for changing which file is added as an asset.

  • Open: Opens the selected asset file in the appropriate editor.

  • Remove: Removes the selected asset file from the Assets tree. The file still exists in repository/workspace.

2.3.4 Problems View

The Problems view shows any problems in the script code that may produce errors or prevent compiling the script. The Problems view shows the following information:

  • # error, # warnings, # infos - shows the number of errors, warning messages, and information messages in the problems view.

  • Description - shows a description of the errors, warning messages, and information messages.

  • Resource - shows the name of the resource file where the error, warning, or information message was generated.

  • Path - shows the script name, workspace, and repository path where the resource file is located.

  • Location - shows the location/line number where the error, warning, or information message was generated.

The following toolbar button is available in the Problems View:

  • Configure the filters to be applied to this view - opens a dialog box for configuring the filters to apply to the Problems View.

2.3.5 Error Log View

The Error Log view shows the error log information for the project and script. The following toolbar buttons are available in the Error Log View:

  • Export Log - exports the error log to a text file.

  • Import Log - imports an error log text file to the Error Log View.

  • Clear Log Viewer - clears all entries from the Error Log View.

  • Delete Log - deletes all logged events.

  • Open Log - opens the log file in a text editor.

  • Restore Log - restores the error log entries from the log file.

You can right-click on a log entry to open the shortcut menu. The shortcut menu includes the same options as the toolbar. The following additional options are available on the shortcut menu:

  • Copy - copies the text for the selected log entry to the clipboard.

  • Event Details - opens the event details dialog with the details for the selected log entry.

2.3.6 Data Table View

The Data Table view is a spreadsheet-like data table for Functional testing scripts. The Data Table content can be changed by manually inputting data into cells or by importing an Excel file before playback. The Data Table content can be changed at runtime using the datatable API or using the user interface when playback is paused by a breakpoint, paused by exception, or paused by clicking the Pause toolbar button. Changes to the Data Table are saved as part of script playback results only. The Data Table and Result Data Table can be exported to an Excel file. See the Oracle OpenScript User's Guide for additional information.

The following toolbar buttons are available in the Data Table view:

  • Import - opens a dialog for selecting an Excel spreadsheet file to import into the Data Table.

  • Export - opens a dialog for specifying where to save the Data Table as an Excel spreadsheet.

You can right-click on a data table cell to open the shortcut Edit menu. The following additional options are available on the shortcut menu:

  • Edit - changes the selected cell to text edit mode. Type data into the cell and press Enter.

  • Cut - cuts the data from the selected cell.

  • Copy - copies the text for the selected cell to the clipboard.

  • Paste - pastes text from the clipboard to the selected cell.

  • Delete - deletes the text from the selected cell.

  • Insert Row Before - inserts a new row into the table before the selected row.

  • Insert Row After - inserts a new row into the table after the selected row.

  • Delete Row - deletes the selected row from the table.

  • Insert Column Before - inserts a new column into the table before the selected column.

  • Insert Column After - inserts a new column into the table after the selected column.

  • Rename Column - opens a dialog box for specifying a new heading name for the selected column.

  • Delete Column - deletes the selected column from the table.

You can right-click on a worksheet tab in the Data Table view to open the worksheet shortcut menu. The following additional options are available on the shortcut menu:

  • Insert Sheet Before - inserts a worksheet tab into the Data Table before the selected worksheet tab.

  • Insert Sheet After - inserts a worksheet tab into the Data Table after the selected worksheet tab.

  • Rename Sheet - opens a dialog box for specifying a new name for the selected worksheet tab.

  • Delete Sheet - deletes the selected worksheet from the Data Table. A confirmation dialog box appears to confirm the deletion.

2.3.7 Object Details View

The Object Details view provides options for viewing the attributes and values for the object selected in the browser connected to the view. The Object Details view is available for Functional tests. See The Oracle OpenScript User's Guide for additional information about using the Object Details view.

The following toolbar buttons are available in the Object Details view:

  • Refresh Tree - refreshes the Object Details tree pane.

  • Find a node to inspect by selecting in browser - starts the capture mode for selecting the Web page object in the browser. Highlight the object in the browser and press F10 to select it and show the attributes in the Object Details View.

  • Connect to browser/Disconnect from browser - connects or disconnects the Object Details View to the browser. The Object Details View must be connected to the browser to capture objects.

The following options are available in the Object Details view:

  • Module - selects the type of OpenScript module. The objects in the tree view change to the specific module type. For example, the Web module shows the HTML DOM tree. The ADF module shows the ADF object tree.

  • Find - provides search capabilities to locate specific text in the Object Details. Type the text to find and click Next or Previous to locate the attributes and values within the tree.

  • Partial Match - when selected the Next or Previous search will match partial text strings specified in Find. When cleared, the Next or Previous search will match the entire Find string.

  • Next - searches down the tree for the next object that matches the Find string.

  • Previous - searches up the tree for the previous object that matches the Find string.

  • Tree pane - shows a tree view of the Document Object Model (DOM). The right-click shortcut menu includes the following options for working with the object selected in the tree:

    • View Object Path - opens a dialog box showing the full path of the object.

    • Add Object Test - opens the Object Test dialog for defining an object test for the object selected in the tree.

    • Add Table Test - opens the Table test dialog box for defining a table test for the table object selected in the tree. This option is only available for table objects.

    • Save to Object Library - opens the Save to Object Library dialog box for saving the object path to an object library.

  • Attribute - shows the attribute name of the object selected in the DOM tree.

  • Value - shows the value of the object attribute selected in the DOM tree.

2.3.8 Script Variables View

The Script Variables view shows the name value of script variables. The script variables are only shown when a running script is paused during playback. To view the script variable values select Script Variables from the View menu, playback the script and click the pause button on the toolbar.

2.3.9 Treeview Breakpoint View

The Treeview Breakpoint view shows the location of breakpoints set in the script tree view. To add a breakpoint to the script tree view, right-click on a script tree node and select Add Breakpoint from the shortcut menu. The Treeview Breakpoint view shows the node, file name, and line number of the breakpoint.

2.3.10 Debug View

The Debug view provides options for debugging script playback. See the Debug View topics in the reference section of the Java development user guide online help for additional information about debugging toolbar options.

2.3.11 Declaration View

The Declaration view shows the source of the element selected in the Java code view. You can open the Java code view of a script and select a script method to view the declaration.

2.3.12 Variables and Breakpoints Views

The Variables and Breakpoints view shows variable values and breakpoints for debugging script playback. See the Breakpoints and Variables View topics in the reference section of the Java development user guide online help for additional information about breakpoints and variables toolbar options.

2.4 Creating a Script Project

You must create a script project to generate the basic structure that you can then customize. The type of script project you create depends upon the type of testing the script is intended to perform: Load Testing (Protocol Automation) or Functional Testing (Browser/GUI Automation) and the Web application that will be tested.

To create a script project:

  1. Select New from the File menu.

  2. Expand a group node and select the type of asset or script to create (see the Oracle OpenScript User's Guide for additional information):

    Functional Testing (Browser/GUI Automation): The Functional Testing group contains the following script types:

    • Adobe Flex: This option lets you create a new script for automated functional testing of web applications that use the Adobe Flex Automation Framework at the browser/gui level.

    • Oracle EBS/Forms: This option lets you create a new script for automated functional testing of Oracle E-Business Suite and other applications that utilize Web and Oracle Forms components at the browser/gui level.

    • Oracle Fusion/ADF: This option lets you create a new script for automated functional testing of Oracle Application Development Framework (ADF)-based applications and other applications that utilize Web and ADF components at the browser/gui level.

    • Oracle JD Edwards EnterpriseOne: This option lets you create a new script for automated functional testing of Oracle JD Edwards EnterpriseOne applications that utilize Web and JD Edwards EnterpriseOne Grid Control components at the browser/gui level.

    • Siebel: This option lets you create a new script for automated functional testing of Siebel applications that utilize Siebel High Interactivity and Standard Interactivity/Web controls at the browser/gui level.

    • Web: This option lets you create a new script for automated functional testing of Web applications at the browser/gui level.

    General: The General group contains the following script types:

    • Block Scenario Script: This option lets you create load scenarios in which they allocate a certain percentage of VUs to run dependent scripts in pre-determined sequences.

    • Database: This option lets you create the basic structure of a Database script for automated testing of SQL statements to test a database and run them in the Oracle Load Testing application.

    • Java Code Script: This option lets you create a new automated test script using your own custom Java code through the OpenScript Eclipse IDE. A basic script structure contains only the Initialize, Run, and Finish nodes. You can edit the script tree or Java code to develop your own custom script. Java Code scripts are typically used for function libraries.

    • Script from Template: This option lets you create a new script from a script that has previously been saved as a template script. When you select this option, you select from a list of previously saved template scripts before specifying the name for the new script.

    • Web Services: This option lets you create the basic structure of a Web Services script for automated testing of Web Services at the SOAP/HTTP protocol level.

    Load Testing (Protocol Automation): The Load Testing group contains the following script types:

    • Adobe Flex (AMF): This option lets you create a new script for load testing of Web applications that utilize HTTP and the Adobe Flex Action Message Format (AMF) protocols at the protocol level.

    • Oracle EBS/Forms: This option lets you create a new script for load testing of Oracle E-Business Suite and other applications that utilize HTTP and Oracle Forms (NCA) protocols at the protocol level.

    • Oracle Fusion/ADF: This option lets you create a new script for load testing of Oracle Application Development Framework (ADF)-based applications and other applications that utilize HTTP and ADF protocols at the protocol level.

    • Oracle Hyperion: This option lets you create a new script for load testing of Oracle Hyperion-based applications and other applications that utilize HTTP and Hyperion correlation rules at the protocol level.

    • Oracle JD Edwards EnterpriseOne: This option lets you create a new script for load testing of Oracle JD Edwards EnterpriseOne-based applications at the HTTP protocol level.

    • Oracle PeopleSoft: This option lets you create a new script for load testing of Oracle PeopleSoft-based applications and other applications that utilize HTTP and PeopleSoft correlation rules at the protocol level.

    • Siebel: This option lets you create a Siebel script structure of a new OpenScript script project. A Siebel script lets you record Siebel Web navigations using a browser for load testing Siebel applications.

    • Web/HTTP: This option lets you create a new script for load testing of Web Applications at the HTTP protocol level.

    Script Asset: The Script Asset group contains the following script asset types:

    • Databank: This option lets you create a new databank or open an existing databank file.

    • Object Library: This option lets you create a new Object Library or open an existing Object Library.

  3. Click Next.

  4. Select the location where you want to store the script project. Scripts can be stored in repositories and workspaces. Load test scripts developed for use with Oracle Load Testing must be stored in a repository/workspace.

    • Path: Shows the file path of the selected repository/workspace.

    • My Repositories: Specifies the repository where the script project will be saved. Select a repository and workspace from the tree. Repositories can be managed using Manage Repositories on the Tools menu.

    • [file list]: List the names of the existing files or scripts in the selected repository/workspace.

    • Script: Specify a name for the script project. The script name is required and must be unique.

  5. Enter a script name.

  6. Click Finish to create a script or select Create as Function Library script and click Next to create a function library.

    For Java Code Scripts, a basic script tree will be created in the script view. You can edit the Java code in the code view. For module scripts, a script tree will be created in the script view. After you record the script, the tree view will contain the navigations and actions depending upon the type script.

    For existing scripts, the file concurrency control prevents multiple users from editing the same script. If you try to open a script that is in use by another user, the script copy wizard opens and you will be asked if you want to make a copy of the script and additional files.

  7. If you are creating a function library, enter a unique Package Name and Class Name to identify the library. The Package Name and Class Name must be unique among all function libraries used by a team. The Package Name and Class Name name should conform to the syntax of a Java class name, and must not contain Double-Byte Character Sets (DBCS). The suggested format for the Package name is "lib.orgName.groupName.subgroupName", for example: "lib.oracle.oats.dev.TestLibrary". The Class Name should be:

    • meaningful and provide context as to the purpose of the library,

    • clear and concise so it is easy to read and type in scripts,

    • something unique so it is not confused with other function libraries.

  8. Click Finish to create the function library. If an existing script is converted to a function library, the initialize, run, and finish sections will appear in the function library, but they only can be called as any other method in the library from caller script.

    When creating function libraries, you can use the menu options to add functions to the library file. Select the Script menu and then select Other from the Add sub menu. The procedure is similar to adding custom functions to a script. See Section 2.7.9, "Using a Script as a Dedicated Function Library" for additional information about creating a function library.

2.4.1 Recording Scripts

OpenScript includes Record capabilities for recording user actions within the application-under-test. After creating a script project, you can use the Record toolbar button or Record menu option on the Script menu to start the recorder for the type of script project. You can specify which section of the script (Initialize, Run, Finish) in which to record using the Set Record Section menu option on the Script menu.

In many cases, it is more convenient to initially record a script against the Web application-under-test and modify the script Java code than it is to create the script in script Jave code.

See Chapter 3 in the Oracle OpenScript User's Guide for additional information about recording scripts.

2.5 Creating Functional Test Scripts

A script project creates the basic structure of an OpenScript script. Initially, the script project includes only the Initialize, Run, and Finish script nodes with the underlying Java code. You use the recording capabilities of OpenScript to record page navigations and generate the Java code for the script.

2.5.1 Creating a Web Functional Test Script Project

To create a functional test script project:

  1. Select New from the File menu.

  2. Select script type under the Functional Testing (Browser/GUI Automation) folder.

  3. Click Next.

  4. Set the Repository/workspace.

  5. Enter a script name.

  6. Click Finish. OpenScript creates the script project and shows the Initialize, Run, and Finish nodes in the Script View.

The resulting script code appears as follows in the Java Code view:

import oracle.oats.scripting.modules.basic.api.*;
import oracle.oats.scripting.modules.browser.api.*;
import oracle.oats.scripting.modules.functionalTest.api.*;
import oracle.oats.scripting.modules.utilities.api.*;
import oracle.oats.scripting.modules.utilities.api.sql.*;
import oracle.oats.scripting.modules.utilities.api.xml.*;
import oracle.oats.scripting.modules.utilities.api.file.*;
import oracle.oats.scripting.modules.webdom.api.*;

public class script extends IteratingVUserScript {
  @ScriptService oracle.oats.scripting.modules.utilities.api.UtilitiesService utilities;
  @ScriptService oracle.oats.scripting.modules.browser.api.BrowserService browser;
  @ScriptService oracle.oats.scripting.modules.functionalTest.api.FunctionalTestService ft;
  @ScriptService oracle.oats.scripting.modules.webdom.api.WebDomService web;

  public void initialize() throws Exception {
  }

  /**
   * Add code to be executed each iteration for this virtual user.
   */

  public void run() throws Exception {

  }

  public void finish() throws Exception {
  }
}

The @ScriptService list will vary depending upon the type of functional test script project created. The script services are used to access the API for each particular service. The following table lists the service names and utilities for the types of functional test script projects:

Table 2-1 Functional Test Script API Service Names

Functional Test Script Type Service Name

Adobe Flex

flexFT.[method]

Applet utilities

applet.[method]

Browser utilities

browser.[method]

Datatable utilities

datatable.[method]

Databank utilities

databank.[method]

Functional test

ft.[method]

Oracle EBS/Forms

forms.[method]

Oracle Fusion/ADF

adf.[method]

Oracle JD Edwards EnterpriseOne

eone.[method]

Shared Data utilities

sharedData.[method]

Siebel

siebelFT.[method]

Utilities (other)

utilities.[method]

Web (base scripting for functional tests).

web.[method]


2.5.2 Recording a Functional Test Scripts

Recording scripts captures the page navigations and generates the Java code that will be used to drive script playback for testing purposes. Web Functional test scripts record and playback actions performed on browser objects.

To record a functional test script:

  1. Select Record from the Script menu or click the Record toolbar button. OpenScript opens a browser window and the OpenScript toolbar window.

  2. Enter the URL of the Web application-under-test into the browser Address line and press Enter.

  3. When the application loads, navigate the application to record browser actions against the application.

  4. Click stop on the OpenScript toolbar to stop recording.

  5. Save the script.

2.5.3 Opening and Closing a Browser

Functional test scripts use browser automation to simulate user actions against a Web application. You can use the browser service API to launch and close the browser and set the browser type programmatically, as follows

browser.launch();
browser.setBrowserType(BrowserType.InternetExplorer);
browser.close();
browser.closeAllBrowsers();

Typically, browser.launch() is used in the initialize() section of the script as the browser only needs to be launched once at the beginning of script playback. browser.close() can be used in the finish() section to close the browser at the end of script playback.

2.5.4 Navigating Web Pages in Functional Test Scripts

Functional test scripts use the web.window() methods to navigate web pages in the browser. Web page navigation is typically performed in the run() section of the script. The following example code navigates the browser to the http://example.com/products.aspx page, then waits for the page to load before continuing script execution:

web.window("/web:window[@index='0' or @title='about:blank']")
  .navigate("http://example.com/products.aspx");
web.window("/web:window[@index='0' or @title='http://example.com/products.aspx']")
  .waitForPage(null);

Once a page is loaded, you can use other API methods to perform actions on the page, for example click a link, as follows:

web.link("/web:window[@index='0' or @title=' Products']" +
  "/web:document[@index='0']/web:a[@text='Mail Order Bikes' " +
    "or @href='http://example.com/bikes/Main.aspx' or @index='5']")
  .click();

2.5.5 About Object Identification Paths

The OpenScript functional test object identification paths specify how the API methods locate and identify browser objects on which to perform actions.

The object identification paths typically follow a hierachical structure as follows:

window
  document
    [form]
      element

In order for the OpenScript playback to perform a click action on a particular button, the object identification path specified in the web.button("path").click method must include the path to the button object, as follows:

web.button(
  "/web:window[@index='0' or @title='Products']" +
  "/web:document[@index='0']" +
  "/web:form[@id='loginform' or @name='loginform' or @index='0']" +
  "/web:input_submit[@name='LoginButton' or @value='Login' or @index='0']")
  .click();

This path specifies that the button is located in the browser window with index value 0 or the title "Products". Within the window is a web document with index value 0. Within the document is a web form with the ID "loginform" or the name attribute "loginform" or the form with index value 0. Within the form is the web input button with the name attribute "LoginButton" or the value attribute "Login" or the index value 0.

Depending upon the module, a method uses a shorter path from within the context set by a previous method.

web.link(30,"/web:window[@index='0' or @title='Oracle Applications Home Page']" +
  "/web:document[@index='0']" +
  "/web:a[@text='Enter' or @href=\"javascript:launchForm('" +
  "http://example.com:8000/OA_HTML/RF.jsp?function_id=2100&resp_id=52297" +
  "&resp_appl_id=8721&security_group_id=0&lang_code=US')\" or @index='35']")
  .click();

forms.button(32, "//forms:button[(@name='CALENDAR_OK_0')]")
  .click();

See the Object Identification tab in the Record Preferences of the specific functional test module for a list of the object names and attributes.

2.6 Creating a Load Test Script

Load test scripts record and playback navigations performed using the HTTP protocol. Load script are typically used for performing load tests on an application using the Oracle Load Testing application.

2.6.1 Creating a Load Test Script Project

To create a load test script project:

  1. Select New from the File menu.

  2. Select script type under the Load Testing (Protocol Automation) folder.

  3. Click Next.

  4. Set the Repository/workspace.

  5. Enter a script name.

  6. Click Finish. OpenScript creates the script project and shows the Initialize, Run, and Finish nodes in the Script view.

The resulting script code appears as follows in the Java Code view:

import oracle.oats.scripting.modules.basic.api.internal.*;
import oracle.oats.scripting.modules.basic.api.*;
import oracle.oats.scripting.modules.http.api.*;
import oracle.oats.scripting.modules.http.api.HTTPService.*;
import oracle.oats.scripting.modules.utilities.api.*;
import oracle.oats.scripting.modules.utilities.api.sql.*;
import oracle.oats.scripting.modules.utilities.api.xml.*;
import oracle.oats.scripting.modules.utilities.api.file.*;

public class script extends IteratingVUserScript {
  @ScriptService oracle.oats.scripting.modules.utilities.api.UtilitiesService utilities;
  @ScriptService oracle.oats.scripting.modules.http.api.HTTPService http;

  public void initialize() throws Exception {
  }

  /**
   * Add code to be executed each iteration for this virtual user.
   */

  public void run() throws Exception {

  }

  public void finish() throws Exception {
  }
}

The @ScriptService list will vary depending upon the type of load test script project created. The script services are used to access the API for each particular service. The following table lists the service names and utilities for the types of load test script projects:

Table 2-2 Load Test Script API Service Names

Load Test Script Type Service Name

Adobe Flex (AMF)

amf.[method]

Databank utilities

databank.[method]

Datatable utilities

datatable.[method]

Oracle EBS/Forms

nca.[method]

Oracle Fusion/ADF

adfload.[method]

Shared Data utilities

sharedData.[method]

Siebel

siebel.[method]

Web/HTTP (base scripting for load tests).

http.[method]

Utilities (other)

utilities.[method]


2.6.2 Recording a Load Test Script

To record an load test script:

  1. Select Record from the Script menu or click the Record toolbar button. OpenScript opens a browser window and the OpenScript toolbar window.

  2. If asked if you want to clear the cache, click Yes.

  3. Enter the URL of the Web application under test into the browser's Address bar and press Enter.

  4. When the application loads, navigate the application to record the HTTP protocol traffic between the web browser and the web server.

  5. Click stop on the OpenScript toolbar to stop recording.

  6. Save the script.

2.6.3 Setting the User Agent and Language Type

Load test scripts use protocol automation to send requests and receive responses from the web server. A browser instance is not required. However, the request header typically sent by a browser. The request header specifies the type of request and sets various settings, such as the host name, Accept settings, Connection setting, User Agent settings, etc. The following example shows a GET request heading:

GET /Stocks HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; 
SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 
6.0; .NET4.0C; .NET4.0E; InfoPath.2)
Host: example.com
Accept: text/html, image/gif, image/jpeg, */*
Accept-Language: en-us
Connection: Keep-Alive
Accept-Encoding: gzip, deflate

By specifying the user-agent string, you can simulate other types of browsers during load script playback. You can use the http.setUserAgent method to set the user agent settings, as follows:

http.setUserAgent("Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; " +
  "WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; " +
  ".NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.2)");

Typically, http.setUserAgent() method used in the initialize() section of the script as the setting is set once at the beginning of script playback.

The request Accept-Language setting is used to specify which languages are acceptable for the response. The setting is set using the http.setAcceptLanguage() method. The String parameter specifies the ISO-639 language abbreviation and optionally a ISO-3166 country code, as follows:

http.setAcceptLanguage("en");
-or-
http.setAcceptLanguage("en-us");

Typically, http.setAcceptLanguage() method used in the initialize() section of the script as the setting is set once at the beginning of script playback.

2.6.4 Navigating Web Pages in Load Test Scripts

Load test scripts use the http.get() and http.post() methods to navigate web pages. Web page navigation is typically performed in the run() section of the script. The following example code send and HTTP request to the server to for the Web document http://example.com/default.asp:

http.get(4, "http://example.com/default.asp", null, null, true,
  "ASCII", "ASCII");

You can use other API methods to perform actions on the response, for example, extract values from the document, as follows:

{
 http.solveXPath("web.formaction.loginform", ".//FORM[@name='loginform']" +
  "/@action", "default.asp", 0, EncodeOptions.None);
 http.solveXPath("web.input.login", ".//INPUT[@name='login']" +
  "/@value", "ta287", 0, EncodeOptions.None);
 http.solveXPath("web.input.password", ".//INPUT[@name='password']" +
  "/@value", "ta", 0, EncodeOptions.None);
http.solveXPath("web.input.LoginButton", ".//INPUT[@name='LoginButton']" +
  "/@value", "Login", 0, EncodeOptions.None);
}

The http.post() method is used to pass postdata to the Web server, as follows:

http.post(10,"http://example.com/{{web.formaction.loginform,default.asp}}",
  null, http.postdata(http.param("login","{{web.input.login,ta287}}"),
    http.param("password", "{{web.input.password,ta}}"),
    http.param("LoginButton","{{web.input.LoginButton,Login}}")),
  null, true, "ASCII", "ASCII");

2.7 Modifying Scripts

Once you have created a script project, you can customize the script for your specific testing purposes using the available menu options or editing your own code in the Java Code view.

2.7.1 Adding Step Groups to a Script

Step groups provide a way to group multiple procedures into a single reporting step.

To add a manual step group to a script in the Java code:

  1. Open or create a script project.

  2. Select the Java Code view and add the beginStep() and endStep() methods as follows:

    beginStep("Step Group 1", 10);
    {
            /**
             * Add code to be executed for the step group.
             */
           info("Step Group 1");
    }
    endStep();
    

    The first parameter is a String specifying the step group name. The second parameter is an optional value specifying the amount of time to wait in milliseconds before beginning the step. The delay value will be adjusted based on the VUser's current delay settings.

  3. Add code to the step group.

2.7.2 Adding a Delay to a Script

To add a delay to a script:

  1. Open or create a script project.

  2. Select the Java Code view and add the think() method with a Double time value in seconds as follows:

    {
    think(10.0);
    }
    

2.7.3 Adding a Log Message to a Script

To add a log message to a script:

  1. Open or create a script project.

  2. Select the Java Code view and add the info(), warn(), or fail() method with a String specifying the message, as follows:

    info("Message");
    warn("Message");
    fail("Message");
    

The log message text appears in the Console View when the script is played back. The info() method is similar to a printf command.

Warning messages report the error as a warning and continue script execution. Fail messages report the error as failure and stop script execution.

2.7.4 Encrypting and Decrypting Data

To add encrypt and decrypt data in a script:

  1. Open or create a script project.

  2. Select the Java Code view and add the encrypt() and decrypt()methods with a String specifying the text to encrypt or decrypt, as follows:

    String encrypted = encrypt("encrypt this string");
      info(encrypted);
    String decrypted = decrypt(encrypted);
      info(decrypted);
    

2.7.5 Setting the Password Encryption

The Password encryption is set in the General Preferences. To set the password encryption:

  1. Select OpenScript Preferences from the View menu.

  2. Expand the OpenScript node and the General category.

  3. Select Encryption.

  4. Select Obfuscate script data or Encrypt script data to make sure the connection to the Shared Data Service uses an obfuscated or encrypted password.

  5. If you select Encrypt script data, enter a password.

  6. Click OK.

The password must be the same on all machines that will edit or playback this script.

2.7.6 Running a Child Script from Within a Script

You can add a method to run another child script from within the current script using the getScript("alias").run(iterationCount) method.

  1. Open or create a script project.

  2. Select the Java Code view and add the getScript("alias") .run(iterationCount) method with a String specifying the alias of the script to run and the iteration count, as follows:

    getScript("alias").run(1);
    

You must also add the child script to the current script as a script asset to run the child script..

2.7.7 Calling a Function from a Child Script from Within a Script

You can add a method to run another child script from within the current script using the getScript("alias").run(iterationCount) method.

  1. Open or create a script project.

  2. Select the Java Code view and add the getScript("alias") .callFunction("functionName", "args") method with a String specifying the alias of the script to run, the function and the function arguments, as follows:

    getScript("alias").callFunction("functionName", "args");
    

You must also add the child script to the current script as a script asset to call the function in the child script..

2.7.8 Adding a Function to a Script

You can add your own custom functions to your script and specify the arguments to pass to the function. Custom functions can be in the current script or in another script or function library script that has been added to the current script's Scripts Assets Properties. See Section 2.7.9, "Using a Script as a Dedicated Function Library" for additional information about creating a dedicated function library script.

To add a function to a script:

  1. Create a script project.

  2. In the Java Code view, add the public void function name to the script code followed by the arguments with the data types:

    /**
     * My custom Function
     * @param argString Description of argString
     * @param argInt Description of argInt
     * @param argDouble Description of argDouble
     * @param argLong Description of argLong
     * @param argBool Description of argBool
    */
    public void myFunction(@Arg("argString") String argString,
          @Arg("argInt") int argInt,
          @Arg("argDouble") double argDouble,
          @Arg("argLong") long argLong,
          @Arg("argBool") boolean argBool)
       throws Exception {
    
  3. Add items into the Function. You can use the Tree View drag/drop or cut/paste features to move Tree View items to the function. You can use the Script Add option to add variable items to the function. You can also use the Code View to add custom code to the function.

To pass arguments into a function:

Define the variables to use to pass values to the custom function arguments somewhere in the script before where the Call Function statement will be placed in the script:

In the Java Code view, add the getVariables().set() statement to the script code followed by the variable name and value for each variable:

getVariables().set("MyString", "String");
getVariables().set("MyInt", "1");
getVariables().set("MyDouble", "12.34");
getVariables().set("MyLong", "1234560");
getVariables().set("MyBool", "True");

The following is an example of a variable set to a Databank value:

getVariables().set("MyString", "{{db.customer.FirstName,String}}");

In the Java Code view, the message statement (info, warn or fail) or getVariables().set() statement will be added to the script code followed by the variable name and value for each variable:

public void myFunction(@Arg("argString") String argString,
      @Arg("argInt") int argInt,
      @Arg("argDouble") double argDouble,
      @Arg("argLong") long argLong,
      @Arg("argBool") boolean argBool)
   throws Exception {
      info("{{arg.argString}}");
      getVariables().set("MyArgString", "{{arg.argString}}");
      getVariables().set("MyArgInt", "{{arg.argInt}}");
      getVariables().set("MyArgDouble", "{{arg.argDouble}}");
      getVariables().set("MyArgLong", "{{arg.argLong}}");
      getVariables().set("MyArgBool", "{{arg.argBool}}");
}

To call a custom function in a script:

In the Java Code view, the callFunction, getScript("ScriptAlias").callFunction(), or className.function()statement will be added to the script code followed by the function name and arguments. If the function is in the same script, the callFunction statement is added:

callFunction("myFunction", "MyStringArg");

To pass data types other than String, enclose a defined variable name in double curly braces as follows, "{{VarName}}".

callFunction("myFunction", "{{MyString}}", "{{MyInt}}", "{{MyDouble}}", "{{MyLong}}", "{{MyBool}}");

If the function is in a another script (a script containing functions that has been added to the current script as a script asset), the getScript("myScriptAlias").callFunction("myCustomFunction", "args"); statement is used to call the function similar to the following example:

getScript("myScriptAlias").callFunction("myCustomFunction",
  "MyString", "true", "2", "10.5", "100", "list1",
  toList("ListString1", "ListSting2"), toMap("key1=value1"));

If the function is in a dedicated function library script (a script specifically created as a function library that has been added to the current script as a script asset), the className.function("args"); statement is used to call the function similar to the following example:

myFunctionLibrary.myLibraryFunction("MyString", true, 2, 10.5, 100,
  "list1", toList("ListString1", "ListString2"),
  toMap("key1=value1"));

See Section 2.7.9, "Using a Script as a Dedicated Function Library" for addition information about dedicated function libraries.

2.7.8.1 Adding Functions that Use Lists

The Type options of the Argument dialog box used when adding a function to a script includes a List<String> type that can be used to create a function that accepts a list of values as a parameter.

The following example code shows a function that uses List<String> for one of the parameter values:

/**
 * a function that uses List<String> parameter.
 * @param user a String specifying the user name.
 * @param password a String specifying the password.
 * @param urls a List<String> specifying the urls.
 */
public void myListFunction(@Arg("user") String user, 
      @Arg("password") String password, 
      @Arg("urls") java.util.List<String> urls)
   throws Exception{
   }

When the user calls the function using the Script menu options, the Call Function dialog box will include a multi-line text box that allows a list of values to be entered. In the Java Code view, the callFunction() code will include a toList parameter similar to the following example:

callFunction("myListFunction", "testuser", "testpwd", toList(
    "http://mysite.com/url1.html",
    "http://mysite.com/url2.html",
    "http://mysite.com/url3.html"));

If the function is in a function library script (a function library script added as a script asset), the ClassName.function() statement is used to call the function similar to the following example:

MyClassNameAlias.myListFunction("testuser", "testpwd", toList(
    "http://mysite.com/url1.html",
    "http://mysite.com/url2.html",
    "http://mysite.com/url3.html"));

2.7.8.2 Adding Functions that Use Maps

The Type options of the Argument dialog box used when adding a function to a script includes a Map<String, String> type that can be used to create a function that accepts key/value pair maps as a parameter.

The following example code shows a function that uses Map<String, String> for the parameter values:

/**
 * a function that uses Map<String, String> parameter.
 * @param keyandvalue a Map<String, String> specifying key/value pair maps.
 */
public void myMapFunction(
      @Arg("keyandvalue") java.util.Map<String, String> keyandvalue) 
   throws Exception {
   }

When the user calls the function using the Script menu options, the Call Function dialog box will include a multi-line text box that allows a key/value pair maps to be entered. In the Java Code view, the callFunction() code will include a toMap parameter similar to the following example:

callFunction("myMapFunction", toMap(
    "key1=value1",
    "key2=value2",
    "key3=value3"));

If the function is in a function library script (a function library script added as a script asset), the ClassName.function() statement is used to call the function similar to the following example:

MyClassNameAlias.myMapFunction(toMap(
    "key1=value1",
    "key2=value2",
    "key3=value3"));

2.7.8.3 Adding Functions that use Enumerated Lists

The Type options of the Argument dialog box used when adding a function to a script includes a Select List type that can be used to create a function that accepts a value from a known list of values as parameters.

The following example code shows a function that uses Select List for the parameter values:

/**
 * a function that uses Select List parameter.
 * @param color a Select List specifying enumerated list of color values.
 */
public void mySelectListFunction(
      @Arg("color") @Values( { "red", "blue", "green" }) String color) 
   throws Exception {
   }

When the user calls the function using the Script menu options, the Call Function dialog box will include a select list box that allows a single value from a list of values to be selected. In the Java Code view, the callFunction() code will include the function name and selected parameter similar to the following example:

callFunction("mySelectListFunction", "blue")

If the function is in a function library script (a function library script added as a script asset), the ClassName.function() statement is used to call the function similar to the following example:

MyClassNameAlias.mySelectListFunction("blue");

2.7.8.4 Inputting Values from a File

The list and map functions can also specify one or more files as an alternate method for inputting list or map data to function arguments using the @dataFile variable. The @dataFile variable specifies the optional repository name, data file path, and optional file encoding using the following format:

{{@dataFile('repository','relativeFilePath')}} 
{{@dataFile('repository','relativeFilePath','encoding')}} 

Create data files containing the appropriate function argument data.

For list functions that use toList(), the data file might appear similar to the following example:

    "http://mysite.com/url1.html"
    "http://mysite.com/url2.html"
    "http://mysite.com/url3.html"

For map functions that use toMap(), the data file might appear similar to the following example:

    "key1=value1"
    "key2=value2"
    "key3=value3"

The toList() and toMap() methods also parse all arguments for any newline delimiters. Any newline delimiters embedded in a value or file will be converted into new list entries. For example,

"value1\r\nvalue2\r\nvalue3"

is equivalent to:

"value1"
"value2"
"value3"

When the user calls a function that uses lists or maps as argument values using the Script menu options, the Call Function dialog box will include the Substitute Variable icon next to the Arguments values field.

Click the Substitute Variables icon next to the Arguments values field.

Expand the @Functions tree, select @dataFile, and click Finish.

The argument value field will contain the {{@dataFile('repository', 'relativeFilePath')}} transform variable. Edit the repository and relativeFilePath values to specify the repository name and relative path to the data file containing the data to pass to the function.

  • repository - specifies the name of the repository where the data file is located. The repository argument can be left blank (using two single quotation marks '') if a relative path is specified for the data file.

  • relativeFilePath - specifies the path and file name of the data file. The file path is relative to the script directory. If the repository is not specified (''), then relativeFilePath should begin with ../.

  • encoding - specifies the file encoding to use. Although not automatically added the in the @dataFile() default value, the file encoding can be added as a third String value in the @dataFile() variable. For example, UTF-8, cp1252 (ANSI), SHIFT-JIS, cp1250 (Central Europe), cp1251 (Eastern Europe).

When you click OK, the function will be added to the tree view similar to the following:

myMapFunction(toMap({{@dataFile('myRepo','files/datafile.txt','cp1252')}}))

In the Java Code view, the callFunction() code will include the function name and @dataFile() variable similar to the following example:

callFunction("myMapFunction", toMap(
  "{{@dataFile('myRepo','files/datafile.txt','cp1252')}}"));

If the function is in a function library script (a function library script added as a script asset), the ClassName.function() statement is used to call the function similar to the following examples:

MyClassNameAlias.myMapFunction(toMap("{{@datafile('','../files/datafile.txt'}}"));

MyClassNameAlias.myListFunction("user", "pwd", 
   toList("{{@datafile('','../files/datafile.txt'}}"));

2.7.9 Using a Script as a Dedicated Function Library

You can create a script that can be used as a dedicated function library that can be used by other scripts as a script asset. The dedicated function library script can contain custom functions that can be called from other scripts. A dedicated function library provides a way for having code assistance in scripts calling functions from the library. Code Assist or Content Assist provides you with a list of suggested completions for partially entered strings. In the Java editor press Ctrl+Space or select Content Assist from the Edit menu.

When creating dedicated function library scripts, you should make the library either a generic Java code script or the same type as the scripts (that is, Web, HTTP, Siebel, etc.) that will be calling functions from the library.

2.7.9.1 About Function Libraries

This section provides basic information and Frequently Asked Questions (FAQs) about function libraries.

What is a function library?

A function library is a means to make your code more reusable and modular. Any script can be used as a function library by creating a library of custom functions within the script code. The function library script can then be added to other scripts as a script asset. The other scripts can then call custom functions from the function library script.

What is the difference between a function library and a regular script?

In general, there is only a minor difference between a function library script and regular script. A function library is a script which you can record into and play back but also includes a unique package and class name. However, function library scripts are generally not intended to be played back. You use a function library script as an asset for other scripts that can call the custom functions contained in the library. Function library scripts include the Initialize, Run, and Finish methods the same as a regular script. The Initialize, Run, and Finish methods in a dedicated function library script are not intended to be called from other scripts. The Initialize, Run, and Finish methods are provided for debugging function library scripts before publishing them.

How do I create a function library?

Before OpenScript version 12.1.0.1, regular scripts were used as function libraries. Users simply added custom functions to a script which was designated as a function library. See Section 2.7.8, "Adding a Function to a Script" for additional information about adding functions to a script. OpenScript version 12.1.0.1 introduces dedicated function library scripts. See Section 2.7.9.2, "Creating a Dedicated Function Library Script" for additional information about creating a dedicated function library script.

What are the advantages of using a dedicated function library?

There are three main advantages to using dedicated function libraries compared with using a script containing functions:

  • The primary advantage is provided for teams that widely use the Java Code view with custom code. The style of calling functions from a dedicated function library script is much more straight forward and clear. For example, with the dedicated function library you call a function a function foo in the library with alias myLib as follows:

    myLib.foo("myArg"); 
    

    With custom functions in a regular script, you call a function using the Reflection style, as follows:

    getScript("myLib").callFunction("foo", "MyArg")
    
  • A second advantage of a dedicated function library is that the direct style of calls provides code assistance in the Java Code view for calling functions stored in a dedicated function library script. There is no code assistance in the Java Code view for calling functions stored in a regular script and called using the callFunction method.

  • A third advantage of a dedicated function library is the ability to use custom classes in the library.

What are the disadvantages of using a dedicated function library, versus using a script with functions in it?

There are some disadvantages to using dedicated function libraries compared with using a script containing functions:

  • A dedicated function library not only has a unique script location, but also a unique library class name. The library class name is rendered when creating the dedicated function library and cannot be changed. If for some reason you need or want to change function library class name (for example, a duplicated function library name was found or something else), you will need to create a new script by selecting Save As from the File menu or by creating a script from an existing script. You will need to enter a new name for the function library class and a new script will be created. The new script will have all of the functions declared in the old function library.

  • Another minor disadvantage of using a dedicated function library is that it needs to be assigned as an asset to each script that uses it. In contrast, using getScript("funcLib").callFunction(), you only need to assign a function library as an asset with the alias "funcLib" to the top level script. Any child scripts will find the function library by its alias during runtime. However, this usage is blind as users have no Tree View or dialog support for inserting such code. By not assigning the dedicated function library directly to a script as an asset, you can only call its functions by typing code directly into the Java code view using the Reflection style syntax. Also, code assistance is not provided for Reflection style syntax.

How can I use a common function library in all scripts I create?

Particularly when creating many test scripts, it can be time consuming to attach commonly used function libraries to each one individually. There are two approaches to solve this problem.

  1. Create Scripts from an Existing Script

    You can create an empty script and attach to it all the common function libraries you want your scripts to use. Each time you create a new script, select New from the File menu, select Script from Template in the General section, then select the script with your common functions to create the new script. Each new script will have the common function libraries attached to it. Any saved script can be a template script.

    The one downside to attaching a function library to every script. If you physically move a function library to a different location on disk, then all existing scripts referencing it from the old location will break.

  2. Attach Function Libraries to a Parent "Master" Script

    If you have a test setup where one parent "master" script calls several "child" scripts, you can attach the common function libraries only to the parent script and not attach it to any child scripts. Child scripts will be able to directly call the function libraries from Java Code using the reflexive code syntax. For example

    getScript("myLib").callFunction("foo", "MyArg");
    

    The benefit to attaching the function library to the parent script, and not to the child scripts, is that if the function library is moved to a different location, you only need to update the parent script with the new function library location. All child scripts will continue to work. However, using this approach, child scripts cannot use the explicit code syntax when calling functions. For example:

    myLib.foo("MyArg");
    

    Child scripts will not be able to use any custom classes exposed by the function libraries or leverage any Java Code assistance features. The child scripts' Tree view will also not provide any UI for adding available functions. This approach is only recommended for teams not relying on the Tree view UI for adding function calls.

Will my existing pre-12.1 function libraries continue to work in new releases?

Yes. See "Opening Existing Scripts" in Chapter 2 of the Oracle OpenScript User's Guide for additional information about backwards compatibility of scripts. Existing scripts and function libraries will continue to work, unmodified, in newer releases.

If you want to take advantage of new features such as code assistance, custom classes, and the explicit function calling syntax, then you would need to create a dedicated function library. However, it is optional if you want to convert your existing script-based function libraries into dedicated function libraries or leave them as regular scripts.

What happens if two different dedicated function library scripts used in a test suite have the same library class name?

Using two function libraries with the same library class name will cause your script to behave unpredictably. Most likely, the OpenScript script editor will display an error when it compiles the script, indicating that some particular method or class cannot be found. This is why, when you are creating a name for library class, it is better to use a long package path to differentiate your library class from other libraries. For example, lib.TestLib is a poor choice. A much better choice would similar to: lib.myCompany.myTeam.framework2.UtilLib.

Can I use custom classes as arguments and return values for functions in function libraries?

You can only use custom classes as arguments and return values for functions in dedicated function libraries. In order for custom classes to be visible to calling scripts they should reside in package "lib" that is automatically created for each dedicated function library. If the author of the function library needs some internal custom classes, then their place is in a sub-package of "lib" package. This way they will be hidden from other scripts. It is better not to put any additional classes in the package where library class itself resides.

Be cautious and do not overuse custom classes. The user of the function library will not get help from UI or code assistance for them. Almost any task can be achieved with the set of data types provided in the OpenScript UI for providing assistance, which includes all primitive types, Enum(selection), List<String>, and Map<String, String>.

I have a function in a function library that returns a custom type. How do I to save it for later use?

You will need to know what type is returned and save it in a script or java variable. Note that OpenScript does not support declaring custom functions (in regular scripts or dedicated function library scripts) that expect the varargs argument feature. That is, arg type, Something...). For example, Foo(String name, String... args);.

Also, having an argument type of List is always preferable to argument of type Array. Thus List<String> is better than Array[]. The reason is creating functions with argument that has an Array type requires the users of the function resolve any ambiguity of casting Array[] vararg type, as it could be cast to Object or Object[].

My function library needs to use third-party JAR files. How I can I do it?

A function library is a script. Assign the JAR file to the script as a generic JAR script asset. You will then have access to all public methods from the Java Code view. Code assistance will help you add the required import statements and call methods in the code view.

Note:

Generic JAR files should not contain any code that uses OpenScript API or Eclipse API.

I would like to expose some methods in third-party JAR files to test scripts to be able to call them. What I should do?

You can assign this JAR file to each script that is going to use it as a script asset. However, it is a blind way for users to call functions in JAR file. A better way is to assign this JAR file to a function library script and wrap the methods in the JAR file that will be called by scripts within functions in the function library. You will be able to control access to the JAR file and, more importantly, add extensive comments on when and how to use these methods. This will benefit the other members in your group by making the use of the functions easier.

What help should I provide to users of my function library?

Function library developers should provide meticulous and extensive Javadoc comments for each function in the function library. The Javadoc comments are what the user sees about each function in the Tree View and as code assistance in the Java Code view.

2.7.9.2 Creating a Dedicated Function Library Script

To create a dedicated function library script:

  1. Select New from the File menu.

  2. Select the project type and click Next.

  3. Enter a script name for the function library (for example, myScriptLib).

  4. Select Create script as a Function Library.

  5. Click Next. The script wizard opens the Create Function Library options:

    Package: Specifies a unique Package name for the function library. Package must be a valid Java Package name that matches A-Z, a-z, 0-9, _. It must not contain spaces or Double-Byte Character Sets (DBCS). The initial default value is myCompany.myTeam. Subsequently, the default value will be set to the last value specified.

    Class: Specifies a unique alias to use as the name (typically the Class name) for the function library script. Class must be a valid Java Class name that matches A-Z, a-z, 0-9, _. It must not contain spaces or Double-Byte Character Sets (DBCS). The Class Name should be:

    • meaningful and provide context as to the purpose of the library,

    • clear and concise so it is easy to read and type in scripts,

    • something unique so it is not confused with other function libraries.

  6. Enter a unique Package name for the function library in the form:

    orgName.groupName.subgroupName
    

    For example:

    oracle.oats.dev
    
  7. Enter a unique alias to use as the Class name for the function library to identify the library. For example:

    WebFunctLib
    
  8. Click Finish.

  9. Select the Script menu and then select Other from the Add sub menu.

  10. Expand the Script Functions and Local Script nodes.

  11. Select [New Function] and click OK.

  12. Enter a function name and description.

  13. Click Add to add any arguments to the function.

    • Enter a name, specify the data type, and enter a description for the argument.

    • Click OK to add the argument.

  14. Repeat step 14 for each argument to add to the function.

  15. Click OK to add the function to the script.

  16. Add your custom code to the function.

    • Use the script recorder to record steps.

    • Switch to the Java Code view and edit the code in the function.

  17. Repeat steps 10 through 17 to add additional functions to the library script. See also Section 2.7.8, "Adding a Function to a Script" for additional information about adding functions to a script.

  18. Save the library script.

2.7.9.3 Calling Functions from a Function Library Script

To call functions from the library script:

  1. Create a new script project (for example, masterScript).

  2. Select the Script menu and then select Other from the Add sub menu.

  3. Expand Script Functions.

  4. Select [New Script].

  5. Select the repository and library script.

  6. Specify a script alias or use the default alias. The script alias must be unique for each library script added to a script.

  7. Click OK.

  8. Expand the Script: scriptLibraryAlias node.

  9. Select the function name from the library script and click OK.

  10. If the Call Function dialog box appears, enter the function arguments and click OK. The library script is automatically added to the current script as a script asset (click the Assets tab in the Script view to view script assets).

    The function name appears in the script tree as scriptLibraryAlias.functionName(args, [...])

    In the Java Code view, the @FunctionLibrary assignment will be added to the script code followed by the library Package Name and function library alias entered when the function library was created, as follows:

    @FunctionLibrary("assetAlias") lib.package.assetAlias scriptAlias;
    

    For example

    @FunctionLibrary("Web_func_lib") lib.oracle.oats.dev.Web_func_lib webFunctLib;
    

    Functions called from the function library appear in the Java Code view using the function library alias and called function name and arguments, as follows:

    scriptAlias.functionName("args", "[...]")
    

    For example:

    webFunctLib.selectColor("red");
    

    When you type the function library alias followed by a period in the code view, the code assistance view opens listing the functions available in the function library with the required arguments.

    In the Java Code view, the getScript().callFunction() statement can also be used with the script code followed by the function name and arguments, as follows:

    getScript("scriptLibraryAlias").callFunction("functionName", "args", "[...]")
    

    However, code assistance is not available for functions called using the getScript().callFunction() statement.

  11. Save the master script and play it back to execute the custom functions. See Section 2.7.8, "Adding a Function to a Script" for additional information about passing arguments to functions.

Note:

In the master script, be sure to add a “Launch Browser” command to the Initialize section if it is not in the first function called from the master script.

2.7.10 Converting a Script to a Dedicated Function Library

You can convert existing scripts to a dedicated function library script.

To convert an existing script to a dedicated function library script:

  1. Open the script to convert to a dedicated function library script.

  2. Select Convert to Function Library from the Tools menu.

  3. Specify a unique package name for the function library script.

  4. Specify a unique alias as the Class name for the function library script. See Section 2.7.9, "Using a Script as a Dedicated Function Library" for additional information about package and class names.

  5. Click OK. The converted script is saved and reopened.

2.7.11 Adding Script Assets

You can add assets to a script such as, databanks, generic JAR files, object libraries, or other scripts containing recorded steps or custom functions. The asset must exist before it can be added. Select New from the File menu to record scripts or create databanks and object libraries. You also use the Add option in the Assets tab of the script view to create databanks and object libraries.

To add assets to a script:

  1. Open or create a script project.

  2. Select the Assets tab in the script view . The Assets view has the following options:

    • Databanks: Lists the Databank assets added to a script.

    • Object Libraries: Lists the Object Library assets added to a script.

    • JAR files: Lists generic JAR file assets added to a script.

    • Script: Lists the child script assets added to a script.

    • Add: Opens a file selection dialog box for selecting the file to add as an asset. Expand the My Repositories tree to navigate to a workspace folder containing the file. For Databanks, a submenu opens for selecting CSV file or database-type databanks. For CSV file databanks, you select the file. For database-type databanks, you specify the database driver and connection information.

      Note:

      Any scripts you plan to run, along with any associated assets, in the Oracle Load Testing application must be stored in a repository/workspace that can be accessed by the Oracle Load Testing Controller. If you create new repositories in OpenScript, you should also add the new repositories in Oracle Load Testing.
    • Edit: Opens a file selection dialog box for changing which file is added as an asset.

    • Open: Opens the selected asset file in the appropriate editor.

    • Remove: Removes the selected asset file from the Assets tree. The file still exists in repository/workspace.

  3. Select the type of asset to add and click Add.

  4. Select the asset to add from a repository.

  5. Set the Relative to option. The Relative to current script and Relative to a repository options specify how the current script will locate the specified script asset. The Relative to a repository option locates the script asset by a repository path such as, [Repository: Default] Default!/WebTutor, if the asset is selected from a repository. The Relative to current script option locates the script asset by a relative path such as ../WebTutor. Selecting the The Relative to current script option is not recommended as script-relative paths are more brittle than repository-relative paths if scripts are moved or shared.

    The following are guidelines when using script assets in a team or distributed environment:

    • Do not use Absolute Paths when referring to assets or saving assets. Oracle Load Testing does not support absolute paths.

    • OpenScript, Oracle Test Manager, Oracle Load Testing, and all command-line agents should all use the same shared repository names and paths.

    • Do not refer to an asset in another repository by a relative path.

  6. Click OK to add the asset to the script properties.

  7. Click OK when finished adding script assets to close the script properties.

Script asset information is stored in the assets.xml file located in the script project directory.

2.7.12 Adding a Synchronization Point to a Script

A sync point allows multiple scripts being run as virtual users in Oracle Load Testing to synchronize their actions and interactions with the application under test. Sync points provide the ability to create realistic multi-user situations that may expose resource conflicts such as deadlocks. When you specify a sync point, multiple virtual users executing the script will reach this sync point at various times depending on a number of factors (for example, the speed of the machine).

Sync points cause each virtual user to wait until all virtual users have reached that sync point. Each of the virtual users notifies the master upon reaching the sync point. The master waits for all of the virtual users to notify it and then issues the go-ahead for all the virtual users to continue past that sync point.

Sync points are added to individual scripts (parent or child scripts) when they are created in OpenScript. The execution parameters for sync points are defined in the Oracle Load Testing application.

To add a sync point to an OpenScript script:

  1. Create or open a script in OpenScript.

  2. In the Java Code view, add the syncPointWait("name"); method to the script code, as follows:

    syncPointWait("MySyncPoint");
    
  3. Save the script in OpenScript.

  4. Load the script into the Oracle Load Testing application and specify the execution parameters for the sync point(s) in the load test scenario. See the Oracle Load Testing User's Guide for additional information about specifying the sync point execution parameters.

2.7.13 Setting and Evaluating Script Variables

To add a Set Variable to a script:

  1. Open or create a script project.

  2. In the Java Code view, add the getVariables().set("variable name", "value"); method to the script code:

    getVariables().set("sVar_MyVar", "My_Value");
    

    If you want to evaluate the variable with a value from an OpenScript transform variable (i.e. a variable value contained in {{}} syntax), use the eval() method as follow:

    http.solve("varTitle", "<TITLE>(.+)</TITLE>", "Page Title Error", false, Source.Html, 0);
    
    getVariables().set("sVar_MyVar", eval("{{varTitle}}"));
    //or
    String title = eval("{{varTitle}}");
    info("Title = " + title);
    //or
    info ("Title = {{varTitle}}");
    

2.7.13.1 Variables with Scope

You can use the variables method in the Java code to get or set variable with scope. For example:

variables.set(String name, String Value, Variables.Scope.scope)
variables.get(String name, Variables.Scope.scope)

Script variables are global for all scripts and functions for a single Oracle Load Testing Virtual User.

  • Each Virtual User keeps its own map of script variables.

  • One Virtual User cannot read/write another Virtual User's script variables. The exception is that a Child Virtual User (i.e. a Virtual User as a child script) has access to all variables in its parent Virtual User.

  • All scripts and functions that a Virtual User runs will have read/write access to all the Virtual User's variables.

  • In Functional Testing, a script typically represents only one Virtual User. In Functional Testing, script variables are generally global variables.

There are three scopes:

  • Local - all variables that the current script explicitly defines as local variables.

  • Parent - all variables that the parent (calling) script defines as its own local variables.

  • Global - all other variables not defined in an explicit scope. This is the default scope when no scope is specified. The Global scope is the parent scope of top-level VUser (top-level script). So a top-level script will have two scopes (Global and Parent) that coincide.

    Scope can be used to avoid confusion. If an author of a child script wants to change variables in global or parent scope, the script author should do it explicitly. If the author of a child script wants to change local script-level variables, then Scope Local should be used.

    Child scripts inherit its entire parent script variables. It is not a copy of the variables, it is a reference to the same variables, i.e. getParentVUSer().variables.

The following examples show uses of the Variable Scope:

//local variable
variables.set("user", "rich", Variables.Scope.Local);

//global variable (same as set("myData", "globalData", Variables.Scope.Global);) 
variables.set("myData", "globalData"); 

//parent variable
variables.set("anotherData", "parentData", Variable.Scope.Parent);

getScript("Script2").run();

// "globalData" as parent and global scope for top-level script coincide.
variables.get("myData", Variables.Scope.Parent)

2.7.14 Adding Comments to Script Results

To add comments to script results:

  1. Open or create a script.

  2. Click the Code view tab.

  3. Add comments or warnings using one of the following code examples:

  • Using a step group:

  • beginStep("Any comment string", 0);
    {
    //The comment string appears in the Name column of the Results view.
    }
    endStep();
    
  • Using the getStepResult().addComment method:

  • //The comment string appears in the Summary column of the Results view
    getStepResult().addComment("Any comment string");
    
  • Using the getStepResult().addWarning method:

  • //The warning string appears in the Summary column of the Results view. 
    //addWarning overides addcomment.
    getStepResult().addWarning("Any warning string");
    

2.7.15 Adding Error Recovery to a Script

To add error recovery to a script:

  1. Open or create a script project.

  2. Select the script node where you want to add the error recovery action.

  3. Select the Script menu and then select Other from the Add sub menu.

  4. Expand the General node and select Error Recovery Action.

    Exception: Select the type of exception error. The list will vary depending upon the script type.

    Action: Select the error recovery action: Fail, Warn, Ignore, Report, or Pause as follows:

    • Fail: Report the error as failure and stop script execution.

    • Warn: Report the error as a warning and continue script execution.

    • Ignore: Ignore the error and continue script execution.

    • ReportErrorAndContinue: Report the error to the results log and continue script execution.

    • Pause: Pause playback and wait for user's decision to continue or abort script execution.

  5. Click OK. The log message node is added to the script tree.

  6. In the Java Code view, the setErrorRecovery(scriptType.constant, ErrorRecoveryAction.action); method will be added to the script code:

    setErrorRecovery(BasicErrorRecovery.ERR_VARIABLE_NOT_FOUND, ErrorRecoveryAction.Fail);
    

2.7.15.1 Script Types

The following are the possible values for scriptType in the Java code statements:

BasicErrorRecovery (Basic module)

FormsErrorRecovery (EBS/Forms Functional module)

FTErrorRecovery (Generic Functional module)

HttpErrorRecovery (HTTP module)

NcaErrorRecovery (EBS/Forms Load module)

UtilitiesErrorRecovery (Generic Utilities)

WebErrorRecovery (Web Functional module)

2.7.15.2 Constants

The following are the possible values for constant in the Java code statements:

BasicErrorRecovery (Basic module)

ERR_VARIABLE_NOT_FOUND
ERR_CREATE_VARIABLE_ERRORCODE
ERR_FILE_NOT_FOUND
ERR_SEGMENT_PARSER_ERROR
ERR_BINARY_DECODE
ERR_ENCRYPTION_SERVICE_NOT_INITIALIZED
ERR_GENERIC_ERROR_CODE

FormsErrorRecovery (EBS/Forms Functional module)

ERR_FORMS_FT_ERROR
STATUSBAR_TEST_ERROR

FTErrorRecovery (Generic Functional Module)

ERR_FT_MATCH_ERROR
ERR_OBJECT_TEST_ERROR
ERR_TABLE_TEST_ERROR

HttpErrorRecovery (HTTP Module)

ERR_ZERO_LENGTH_DOWNLOAD
ERR_MATCH_ERROR
ERR_RESPONSE_TIME_ERROR
ERR_SOLVE_ERROR
ERR_HTML_PARSING_ERROR
ERR_INTERNET_INVALID_URL
ERR_INVALID_HTTP_RESPONSE_CODE
ERR_KEYSTORE_LOAD_ERROR

NcaErrorRecovery (EBS/Forms Load Module)

CONNECT_ERROR
MESSAGE_IO_ERROR
CONTROL_INITIALIZE_ERROR

UtilitiesErrorRecovery (Generic Utilities)

ERR_SQL_EXECUTE_ERROR
ERR_XML_PARSING_ERROR
ERR_CSV_LOADING_ERROR

WebErrorRecovery (Web Functional module)

ERR_RESPONSE_TIME_ERROR
ERR_WEBDOM_SOLVE_ERROR
ERR_WAIT_FOR_PAGE_TIMEOUT_ERROR

2.7.15.3 Actions

The following are the possible values for action in the Java code statements:

Fail
Ignore
Warn
ReportErrorAndContinue
Pause

2.7.16 Verifying Script Actions

You can verify script actions to check the result of a script action and adjust the behavior of the script based on the result of the action.

The basic process to use verify script actions is as follows:

  1. Add an Error Recovery Action before the script node where you want to verify the result code. You can add the Error Recovery Action from the script Add sub menu or in the Java Code view. Set the error recovery action to Warn or Ignore to ensure that the Has Error block gets executed. This allows script execution to continue past the code where an exception occurred to the next statement in the script code.

  2. Add a 'Has Error' Control Statement after the script node where you want to verify the result code. You can add the Has Error Control Statement from the script Add sub menu or in the Java Code view. The if(hasLastError()) block is added to the script code directly after the script node where you want to verify the result code.

  3. Add your custom code into the if(hasLastError()) block in the Java Code view.

  4. Add Results Object messages to return the result values. The Result Code Verification features provide access to a Results object. The Result Object provides Result Code, Summary, Error Message, and Duration information.

The following sections explain the steps in more detail.

2.7.16.1 Adding an Error Recovery Action

To add an Error Recovery Action:

  1. Select the script node before the script node where you want to verify the result code.

  2. Select the Script menu and then select Other from the Add sub menu.

  3. Expand the General node.

  4. Select Error Recovery Action and click OK.

  5. Select the Exception type. See Section 2.7.15, "Adding Error Recovery to a Script" for additional information.

  6. Select the Action type and click OK.

  7. Add the Has Error condition to the script. See Section 2.7.16.2, "Adding a Has Error Control Statement" for additional information.

2.7.16.2 Adding a Has Error Control Statement

The Has Error Control Statement can be added to the script using the Tree view. However, the conditional behavior must be specified in the Java Code view.

To add a Has Error condition:

  1. Select the script node after the script node where you want to verify the result code.

  2. Select the Script menu and then select Other from the Add sub menu.

  3. Expand the Control Statements node.

  4. Select Has Error? and click OK. The if (hasLastError()) node is added to the script tree.

  5. Add a Result Object or add your custom code in the if (hasLastError()) block in the Java Code view. See Section 2.7.16.3, "Adding a Result Object Message" for additional information.

2.7.16.3 Adding a Result Object Message

The Result Object can be used to return result values.

To add a Result Object message:

  1. Select the if (hasLastError()) node in the script tree.

  2. Right-click the if (hasLastError()) node and then select Other from the Add sub menu.

  3. Expand the General node.

  4. Select Message and click OK.

  5. Select Info or Warn as the Message Type.

  6. Click Substitute Variable.

  7. Expand Last Result.

  8. Expand All Actions or assertions and Verifications.

  9. Select the Result to add to the message and click Finish.

  10. Click OK to add the message to the script.

    In the Java Code view, the message code with the result type is added to the if (hasLastError()) block:

    info("{{result.summary}}");
    

    You can customize the message string in the Java Code view. For example:

    info("Summary of last action: {{result.summary}}");
    
  11. If necessary drag the message node into the if (hasLastError()) node so the message is a child node of the if (hasLastError()) block. For example:

    if (hasLastError()) {
        info("Summary of last action: {{result.summary}}");
    }
    

2.7.16.4 Actions That Can Be Verified

Only specific OpenScript actions provide the ability to verify their results. In general, all actions that are available for adding from the tree view UI, including all verifications and assertions, support verification.

The following types of actions typically do not support verification:

  • Java methods that are only available from code and not from the UI

  • Deprecated methods

  • "Get" methods

  • Methods that interact with OpenScript internal code such as Logger, VUDisplay, Settings, Counters

  • Methods that don't throw any exceptions, such as http.removeCookie

2.7.17 Chaining Multiple Scripts

You can run multiple scripts from within a single script to chain playback of scripts together.

The procedure involves the following major steps:

  • Setting the browser preferences

  • Recording scripts

  • Creating a shell script

2.7.17.1 Setting the Browser Preferences

The browser preferences specify if a new browser will launch when recording a different script. Because the navigation sequence between multiple scripts is important, the same instance of the browser should run all scripts if the scripts are a continuation of each other. If each script is self-contained and there is no navigation between scripts, each script can launch its own browser and you can skip the Browser Preferences steps.

  1. Select Preferences from the View menu.

  2. Expand the General category and select Browsers.

  3. Clear the Always launch a new browser when recording a different script option.

  4. Click OK.

2.7.17.2 Recording Scripts

When recording scripts for chained playback, it is important to plan the start and stop points between scripts. This is especially true if session state needs to be maintained between scripts. All of the scripts must be of the same type.

  1. Create and record the first script, for example a Web Functional test log in script.

  2. Stop the recording but do not close the browser.

  3. Save the script.

  4. Create and record the next script. The navigation in this script should start from the point in the browser where the first script stopped.

  5. Stop the recording and save the script.

  6. Create and record any additional scripts to chain. The navigation in these script should start from the point in the browser where the previous script stopped.

2.7.17.3 Creating a Shell Script

The shell script is used to run the previously recorded scripts in sequence.

  1. Create a new script to use as the shell script.

  2. Select the script node where you want to add the first script. This could be either the Initialize or Run nodes.

  3. Select the Script menu and then select Other from the Add sub menu.

  4. Expand the General node and select Run Script.

  5. Click OK.

  6. Click New.

  7. Select the script to run from the available script assets in the Script properties. Use the Add button to add scripts to the script assets properties.

  8. Click OK.

  9. Select or clear the script sections to run and the iteration count.

  10. Click OK.

  11. Select the script node where you want to add the next script. This could be either the Initialize, Run, or Finish nodes.

  12. Select the Script menu and then select Other from the Add sub menu.

  13. Expand the General node and select Run Script.

  14. Click OK.

  15. Click New.

  16. Select the next script to run from the available script assets in the Script properties. Use the Add button to add scripts to the script assets properties.

  17. Click OK.

  18. Select or clear the script sections to run and the iteration count.

  19. Click OK.

  20. Repeat the Add script steps for each additional script to run.

  21. Save and playback the shell script to verify the script navigations work together correctly.

  22. In the Java Code view, the getScript().run() methods will be added to the script code:

    getScript("Web1").run(1);
    getScript("Web2").run(1);
    

2.7.18 Aborting and Resuming a Script Programmatically

The Application Programming Interface (API) includes methods for aborting and resuming a script programmatically.

The abort() method immediately aborts the Virtual User as soon as possible. The remaining actions in the iteration, including any parent scripts and functions, will not complete. The Finish section will not be run. The currently running script will return a failed result indicating that the Virtual User was aborted.

If a Virtual User is aborted, it is possible to resume the script by catching the abort user exception and calling resume().

The resume() method allows the caller to reset a previously fired abort() request so that script execution can successfully continue from that point on. The caller must first catch the StopScriptRuntimeException that gets thrown by the abort() request and then call resume().

The resume() method works together with the abort() method. Calling resume() will only recover from a previously called abort().

The following examples show how to use the abort() and resume() methods.

//Example Use Case 1 - Abort a script at any point
info("Running a script...");
abort();
info("This line will not be run.");

//Example Use Case 2 - Abort a script and resume
try {
  info("Perform any steps inside a try-catch block...");
  abort();
  info("This line will not be run.");
}
catch (StopScriptRuntimeException e) {
   // optionally take any corrective action and optionally resume script
  resume();
}

//Example Use Case 3 - Abort Script after 5 Minutes and Execute the Finish Section
public void initialize() throws Exception {
  abortAfter(5*60); // Abort after 5 minutes
  try {
     // Insert script Initialize section here
     info("initializing resources");
  }
  catch (StopScriptRuntimeException e) {
     // ignore this and continue to run()
  }
}

public void run() throws Exception {
  try {
     // Insert script Run section here
     http.get(null, "http://myServer/longrunningtask?length=10min");
  }
  catch (StopScriptRuntimeException e) {
     // ignore the exception; OpenScript will run the finish()
  }
}

public void finish() throws Exception {
  resume();
  info("cleanup resources");
  // Insert real customer script Finish section here
}

//Example Use Case 4 - abort() after waiting for the specified amount of time
// Usage Example:
//abortAfter(5); to abort after 5 seconds
//abortAfter(5*60); to abort after 5 minutes
private void abortAfter(int seconds) {
  new Timer().schedule(new TimerTask() {
     public void run() {
       try {
          abort();
       }
       catch (StopScriptRuntimeException e) { /* ignore exception thrown */ }
     }
  }, seconds*1000);
}

2.8 Using Script Databanks

Databanks are used to hold unlimited amounts of input data that can be automatically fed into your Web application. During playback, the parameters in the Web page are filled with values from the Databank file. The Databank and script parameter shortcut menu options allow you to map parameters in a script to fields in a Databank file as variable names.

Scripts must be configured to use Databanks. Use the options on the Assets tab of the script view to specify the Databank file(s) to use with a script. Scripts can be configured to use more than one Databank file.

When you record a script that has a navigation that uses parameters, the parameter nodes appear under the Query String node for HTTP protocol load test scripts:

In the Code View, the parameters appear in the http.param parameters of the http.querystring parameter.

When you configure the Databank(s) to use with the script, the Get next Databank record from databank name node and Java code are added to the script.

Select the script parameter node to map to a Databank and use the Substitute Variable option on the right-click shortcut menu to select the Databank field name to map to the parameter. The Databank file and field name appear in the parameter node of the script tree.

The variable appears in the Code view in the http.param parameters of the http.querystring parameter.

Use the Playback iterations to playback using the records in the Databank. You can also use custom code to loop through Databank records and assign values to variables.

2.8.1 Configuring Databanks

You must configure the Databank to use with a script before you can get records from the Databank to use in a script.

To configure Databanks to use with a script:

  1. Open or create a Script project.

  2. Select the Assets tab in the script view.

  3. Select Databanks.

  4. Click Add.

  5. Select Databank.

  6. Select CSV file or Database. Once a databank is defined as CSV or Database (SQL), the databank type cannot be changed to the other type.

  7. For CSV files:

    1. Select the Repository from the My Repositories tree.

    2. Select the Databank file from the repository.

    3. Set the Type to Databanks (*.csv, *.txt).

      Type: Specifies the type of databank file to add to the script (*.csv, *.txt).

    4. Select the Charset to use.

      Charset - specifies the character set encoding used for the databank file. The suggested charset encoding of the databank .csv file is the native charset of user machine. For US machines the suggested encoding is cp1252. For East European machines, the suggested charset is cp1251. If a databank file was saved with UTF-8 encoding with Unicode byte order mark (BOM), OpenScript detects it, and sets encoding to UTF-8. If the charset used for the databank file is different from the charset of the user machine or UTF-8 with BOM, then you must the correct charset. Otherwise, the databank will not be read correctly and may cause a script failure. You can select the correct charset from the Charset list or enter the correct charset in the field.

      During playback, the Agent will define the charset for reading the databank file in following order:

      • If file has UTF-8 encoding with BOM, then it will be used.

      • The charset specified during asset configuration will be used.

      • If no charset specified, then UTF-8 encoding will be used.

    5. Enter an alias name to use for the Databank or leave the default alias name. The default alias name is the name of the .CSV Databank file.

      Alias: Specifies an alias name to use for the Databank. The Databank file name is the default. The Databank alias name is the name that appears when you add a Databank record retrieval node to a script tree.

    6. Set the Relative to option. The Relative to current script and Relative to a repository options specify how the current script will locate the specified script asset. The Relative to a repository option locates the script asset by a repository path such as, [Repository: Default] Default!/WebTutor, if the asset is selected from a repository. The Relative to current script option locates the script asset by a relative path such as ../WebTutor. Selecting the The Relative to current script option is not recommended as script-relative paths are more brittle than repository-relative paths if scripts are moved or shared.

      The following are guidelines when using script assets in a team or distributed environment:

      • Do not use Absolute Paths when referring to assets or saving assets. Oracle Load Testing does not support absolute paths.

      • OpenScript, Oracle Test Manager, Oracle Load Testing, and all command-line agents should all use the same shared repository names and paths.

      • Do not refer to an asset in another repository by a relative path.

    7. Click OK.

    8. Click OK to add the Databank file.

  8. For Databases, a Databanks Database Assets dialog box appears. This dialog box lets you specify the database and query to use as a databank. Contact your Database Administrator for the appropriate settings for your database. The following options are available:

    1. Specify the Database Driver.

      Oracle Thin - This driver option applies to Oracle databases.

      • Hostname - Specify the host name of the machine running the database. This is not required for a JDBC:ODBC or Custom driver setting.

      • Port - Specify the port for the driver you selected. For example, the default port for an Oracle Thin JDBC driver is 1521. Modify the port number if necessary. This is not required for a JDBC:ODBC or Custom driver setting.

      • SID - Specify the database or server ID.

      • Service name - Enter the Service name used for the Oracle database.

      ODBC - This driver option is available as an option for SQL and Oracle databases and any other database for which you have a JDBC:ODBC Bridge driver.

      • Data Source - Specifies the data source for the ODBC driver.

    2. Specify the URL, username, password, query string, and databank alias.

      • URL - Specifies the URL to use to connect to the database.

      • Username - Enter the username for connecting to the database, if required for authentication.

      • Password - Enter the password for connecting to the database, if required for authentication.

      • Query - Specify a single SQL query that returns all the rows needed as databank values. The SQL query cannot contain PL/SQL or SQL*Plus code. Only pure SQL is supported. You must ensure that the query returns the column names (i.e. databank fields) that the script expects.

        If you have a large database-backed databank, but will only use a small portion of the records in the test, then use the "Where" clause in the SQL query to minimize the amount of records retrieved from the database. For example, if you have database with 200000 records and only need to have 100 iterations retrieving records 201 through 301 sequentially starting from record 201. use a query such as Select * From LargeTable Where id > 200 AND id < 302. The start record will be 1 and no is range set. This reduces the databank preparation time and minimizes the amount of records retrieved from the database.

        Use the "Order By" clause in the query to make sure the results returned from the database are ordered as intended. For example, if you have a database table with Columns id, firstName, and lastName that is populated it with the following data:

        1, John, Smith
        2, Jane, Doe
        [...]
        400, Maria, Sanchez
        [...]
        200000, Sachin, Rajaram
        

        If you use the query Select * From users, the results of query could be unordered, meaning the first record in databank could be 400, Maria, Sanchez instead of 1, John, Smith. Using the query Select * From users Order By id would order the first databank record as 1, John, Smith as expected.

      • Alias: Specifies an alias name to use for the Databank. The Databank alias name is the name that appears when you add a Databank record retrieval node to a script tree.

    3. Click Test to verify the connection to the database.

    4. Click OK.

    5. Click OK to add the Databank file. For Databases used as databanks, a copy of all data is retrieved and indexed before the start of the test. The data is not read live during the test. See Section 2.8.4, "Playing Back Scripts With Iterations" for additional information about playing back scripts with databanks.

2.8.2 Creating or Editing Databank Files

Databank files are comma-separated value (".csv" or ".txt") files with the addition of formatting rules specific for databanks and rules derived from Excel formatting. Databanks can also be data retrieved from a database using an appropriate query to that generates data that conforms to the .csv databank file formatting rules.

When you open a Databank file from the Assets tab of the script view, the Databank file opens in a text editor view. You can edit the Databank file directly in the text editor view. You can also create or edit databank files using another text editor or spreadsheet that can export to .csv formatted text files.

The general databank file formatting rules are as follows:

  • The first line of the databank defines the field headers (column titles). A comma is used as the field header delimiter (no spaces). The field header names are user defined. For example, FirstName,LastName,Mail,Phone defines four field headers for a databank file. The field headers can be referenced in the script code to specify valid databank variables. For example, if the first line of a databank with the alias name "myDB" contains the field headers user and password, the following databank variables are valid in a script configured to use the "myDB" databank: db.myDB.user and db.myDB.password.

  • Each line in the file following the field headers defines a databank record.

  • A line can end with a Line Feed (LF) character or Carriage Return/Line Feed (CR LF) characters.

  • Each databank record consists of field data (columns). A comma is used as the field delimiter (different line for each record, no spaces around commas). For example, John,Smith,JohnS@company.com,x993 defines the field data for a databank record corresponding to the field headers FirstName,Lastame,Mail,Phone.

  • Each databank record must have the same number of fields as the number of field headers. For example, if a databank file has four field headers in line 1 as FirstName,LastName,Mail,Phone, each databank record on lines 2 through n must have four field data columns in each record. The databank field data record john,smith,JohnS@company.com,x993 is correct. However, john,smith,JohnS@company.com is incorrect as this record contains only three fields. Insert an extra comma to leave a field column blank. For example Sachin,Bhat,,x783. As follows:

    FirstName,LastName,Mail,Phone
    John,Smith,JohnS@company.com,x993
    Mary,Ellen,MaryE@company.com,x742
    Sachin,Bhat,,x783
    
  • A quotation mark (") is used as an escape character for embedding new line characters (LF, CR) or comma (,) inside of a databank record. All escaped records, regardless if it has embedded LF, CR, or comma or not, should start with a quotation mark and end with a quotation mark followed by comma or CR/LF. For example, if a data value contains a comma, place quotation marks around the value, as follows:

    John,Smith,"Anytown, MA",(603) 993-0000
    

    New lines may be embedded inside of quotation marks, as follows:

    field1,"field2 contains two lines: Line one.
    Line two.",field3
    

    To use a quotation mark as itself not as an escaped character, escape the quotation mark. The correct format is "". Quotation marks in the middle of a record should be escaped always. For example the following record,

    THIS IS BEGINNING AND ""THIS IS END""
    

    is formatted correctly. The following record,

    THIS IS BEGINNING AND "THIS IS END"
    

    is not formatted correctly.

  • Blank lines are stripped out and ignored.

The character encoding of the CSV file is determined by an (optional) byte-order-mark (BOM) at the beginning of the file. Programs such as Notepad++ or Excel set this byte-order mark when users save a text document with a specific encoding character set like UTF-8. If no byte-order mark is specified, the CSV reader uses character set assigned to a databank asset, when the user adds the databank asset to a script, or uses the current platform's default character set to read the file (for example, cp1252 on most Windows English installations) for legacy databanks prior to Version 9.2.

2.8.3 Getting Databank Records

To get Databank records to use with a script:

  1. Open or create a script project.

  2. Click the Assets tab.

  3. Select Databanks.

  4. Click Add and select the CSV, text or database you want to get databank records from.

  5. In the Java Code view, highlight the text you want to replace with a databank record column.

  6. Right-click the highlighted text and select Substitute Variable.

  7. If necessary, expand the Databanks node and select the Databank field you want to use as the input parameter data.

  8. Click Finish.

  9. In the Java Code view, the parameter code changes to show the Databank alias name, field name, and recorded value as a variable value. For example:.

    http.postdata(http.param("login", "{{db.customer,login,ta906}}");
    
  10. You will also see a line added to the section in which the parameter was substituted, for example:

    getDatabank("customer").getNextDatabankRecord();
    

    In the Java Code view, a getDatabank("databank alias").method (); can be added to the script code depending upon the type of record selected:

    getDatabank("customer").getNextDatabankRecord();
    getDatabank("customer").getFirstRecord();
    getDatabank("customer").getLastRecord();
    getDatabank("customer").getRecord(5);
    

2.8.3.1 Getting Databank Records Using the API

You can use the additional API methods available with getDatabank("databank alias")in the Java Code view to retrieve specific records from the databank. This section provides examples of the available methods.

2.8.3.1.1 Databank API Usage Notes

These API methods are not compatible with databank's iteration settings Randomly or Shuffle Records. The Databank Exception "incompatible with db setting" will be thrown if these methods are used with the Randomly or Shuffle Records iteration settings.

The records obtained through these API calls are not counted against the usage count of all records. It is possible for an infinite script loop to occur if the When Out of Records iteration setting is set to Stop the User, but the script only uses these API calls to read records.

2.8.3.1.2 Loading a Databank

The following example uses the load() method to get a new databank that will override a statically defined databank in OpenScript:

getDatabank("alias").load("repository", "dbPathRelToRepository", "settings");

The load() method is used to programmatically override static databanks in a script. The load() method is used with functional testing scripts only. The parameters for the load() method are as follows:

repository - a String specifying the repository to look inside to locate the databank file. Valid repositories are mapped using the Manage Repositories options on the Tools menu. An example repository could be named "Default" and map to C:\OracleATS\OFT.

dbPathRelToRepository - a String specifying the path to the databank file within the named OpenScript repository. The file extension is not required. For example, it can be specified as "databank1", "databank1.csv", or "databank1.txt". Any leading file separator on the path, such as / or \ is ignored. The dbPathRelToRepository parameter cannot be null.

settings - a String specifying the databank settings to apply to the loaded databank. For example "startIndex=10:select=SEQUENTIAL:whenOut=LOOP_FOREVER". See the -dbopts settings in the General Section of Appendix A of the Oracle OpenScript User's Guide for the databank settings. If null, the settings revert to the default databank settings.

The following example shows how to load a databank file "euroCustomer" dynamically from the Databanks/files folder in the default repository and use the default settings.

public void run(){
 getDatabank("customer").load("default", "Databanks/files/euroCustomer", null);
 getDatabank("customer").getNextDatabankRecord();
 web.textbox("....").setText("{{db.customer.column1}}");
}

The following example shows how to load a databank file "euroCustomer.csv" to dynamically override the statically mapped databank file "customer.csv" from the Databanks/files folder in the default repository and use the default settings.

public void run(){
 //Alias "customer" is defined as a static Databank Asset customer.csv.
 getDatabank("customer").getNextDatabankRecord();
 web.textbox("....").setText("{{db.customer.accountNumber}}");

 //Override Alias "customer" with databank "euroCustomer.csv"
 getDatabank("customer").load("default", "Databanks/files/euroCustomer", null);
 getDatabank("customer").getNextDatabankRecord();
 web.textbox("....").setText("{{db.customer.accountNumber}}");
}
2.8.3.1.3 Getting a Record Count

The following example uses the getDatabankRecordCount() method to get the record count from the "customer" databank and prints the value to the Results view:

int recordCount = getDatabank("customer").getDatabankRecordCount();
info("Record Count = " + recordCount ); 
2.8.3.1.4 Getting a Specific Record

The following example uses the getRecord(n) method to get a specific record from the "customer" databank and prints the value to the Results view:

getDatabank("customer").getRecord(5);

The following code example use a For statement to loop through all records in the databank:

int recordCount = getDatabank("customer").getDatabankRecordCount();
for (int i=1; i<=recordCount; i++) {
   info("Record count = " + i + " of " + recordCount);
   getDatabank("customer").getRecord(i);
}
2.8.3.1.5 Getting the First Record

The following example uses the getFirstRecord() method to get the first record in the "customer" databank:

getDatabank("customer").getFirstRecord();
2.8.3.1.6 Getting the Last Record

The following example uses the getLastRecord() method to get the last record in the "customer" databank:

getDatabank("customer").getLastRecord();

2.8.4 Playing Back Scripts With Iterations

OpenScript allows repetitive playback of navigations in a script. The iterations can be performed with or without databanks.

  1. Start OpenScript.

  2. Open the script to play back.

  3. Configure the script to use a databank as described in Section 2.8.1, "Configuring Databanks".

  4. Select Iterate from the Script menu or click the toolbar button. The resulting dialog box has the following options:

    Use Databanks: When selected, databanks will be used for script playback. Databanks configured for the script show the following settings:

    • Name: Lists the alias name(s) for the databank file(s).

    • Range: Lists the range of databank records to use for script playback. This list corresponds to the Range option selected for each databank file.

    • Start: Lists the starting databank record to use for script playback. This list corresponds to the Starting Record specified for each databank file.

    • Select Record: Lists the how databank records are selected for script playback. This list corresponds to the Select Next Record setting selected for each databank file.

    • When Out of Records: Lists the action to take when the databank file is out of records during script playback. This list corresponds to the When Out of Records setting selected for each databank file.

    • Data: Lists the data in the Starting Record of each databank file.

    Databank Source: This section shows the following information about the selected databank:

    • Alias: Shows the alias name of the selected databank file and the number of rows in the file.

    • Type: Shows the type of the selected databank file. Databanks can be CSV text files or databases.

    • Source: Shows the path and filename of CSV text files or the database query used for database databanks. While there is not a maximum file size, the recommended maximum sizes is 200 MB. The only limitation is how long it takes to generate the index. The databank must be indexable within 30 seconds, by default. This setting is configurable in the "Databank Setup Timeout" setting in the General Preferences.

    Databank Settings: This section specifies the settings to use for the selected databank:

    • Advance to Next Record: Specifies when the virtual user should advance to the next databank record during script playback. The master script being played is always the script that triggers when an iteration occurs. The following options are available:

      • When Script Requests a Record: The databank record advances every time a script explicitly requests a record during script playback. A record request corresponds to the script Java code calling the getDatabank(alias).getNextRecord() method. This is the default behavior.

      • Each Occurance: The databank record advances when a script refers to a databank column (i.e. databank field) in the script. A record request corresponds to the script Java code evaluating a parameterized value such as {{db.fmstocks_data.ticker}}. You can specify that any column advances to the next record or specify a particular databank column advances to the next record. For example, if you have an employee databank with a firstName field and the firstName column is specified as the Column value, the databank record advances only when the {{db.employees.firstName}} value in the script Java code is evaluated on script playback. Select the databank field name as the Column value or select <Any> to allow any field to advance the databank record.

      • Each Iteration of Script: The databank record advances before a script containing the databank starts another playback iteration.

    • Select Next Record: Specifies how a new record is selected from the databank when the databank record advances. The following options are available:

      • Sequentially: The databank records increment one by one in sequential order from the start of the specified range. When multiple virtual users are running, records are distributed in sequential order across all virtual users.

      • Randomly: The databank records are selected at random from the databank. The same record may be used multiple times before all records are exhausted. Random record selection is only provided for databanks that can be indexed. When configuring databank settings, if the databank file is too large to index, the Randomly or Shuffle record options may not be available. The When Out of Records setting does not apply when Random is selected.

      • By Shuffling: The databank records are selected at random from the databank ensuring that once a record is selected, it is never selected again. The setting works similar to selecting a random card from a deck until no cards are left. Shuffle mode only supports databanks containing fewer than 200,000 records. For databanks containing more than 200,000 records, you can shuffle the values in the actual data file or you should use the Randomly mode.

      • Use Seed: Specifies a randomization seed value to use when using the Randomly or Shuffle modes. Use the same seed across multiple tests to create the same sequence of random numbers for all tests. If 0 or not specified, a seed is generated automatically based on the current time.

    • When Out of Records: Specifies the action the virtual user takes if all databank records in the specified range have been used and a new record is requested. The following options are available:

      • Loop Over Range: Loops back to the first record in the range after all records in the range are used and continues distributing records. Use the Maximum Iterations settings to prevent the virtual user from running forever.

      • Keep the Same Record: Continues to use the last record requested after all records in the range are used. No additional records are requested from the databank. Any calls in the Java code to getNextDatabankRecord() are ignored after all records are used. Custom Java code may be used in the script to have Virtual users request an individual record using getRecord(n), getLastRecord(), or getFirstRecord().

      • Stop the User: The virtual user immediately stops running the next time a record is requested from the databank after all records in the range are used. The virtual user will stop regardless of how many iterations are specified by the Maximum Iterations settings.

    • Range: Specifies the range of records to use. The following options are available:

      • All Records: When selected, the virtual user uses all records in the databank. The first record is 1.

      • Specific Records: When selected, the virtual user uses a subset of records in the databank. Specify the first and last records to use for the range. The range includes both the starting and ending record in the specified range.

    • Starting Record: Specifies which databank record to use first. The first record in a databank is 1. The starting record must be within the specified range of records. For example if you select Specific Records and set the range to 5:10, the starting record must be at least 5, but not more than 10.

    Maximum Iterations: This section specifies the maximum number of iterations of a main script's run() section to complete:

    • Run no more than [ ] iterations: Specifies the maximum number of iterations. If a databank exhausts all records and When Out of Records specifies Stop the User, the virtual user will always stop running, even if the specified number of iterations has not completed.

  5. Select Use Databanks.

  6. Select which databank file to specify the settings for if more than one database is configured for the script.

  7. Specify the settings for the databank file.

  8. Select the Run no more than [ ] iterations option and set the iteration count to the desired number of playback iterations.

  9. Click OK.

    You can view the progress of the script playback in the Console View. You can review the results of script playback in the Results View.

2.8.4.1 Notes and Limitations

Certain setting combinations are not allowed, or may cause exceptions when the script is run. The following are situations to be aware of when using iteration options.

  1. The When Out of Records option is not available when Select Next Record is set to Randomly. When random is selected, an infinite supply of random records exists.

  2. Virtual users may still request an individual record using getRecord(n) after all records are used up, and When Out of Records is set to Keep the Same Record.

  3. The getRecord(n), getFirstRecord(), and getLastRecord() Java code methods do not advance the record cursor used by getNextDatabankRecord(). Therefore:

    getNextDatabankRecord();// returns 1
    getRecord(7);// returns 7
    getNextDatabankRecord();//returns 2, not 7
    
  4. The getRecord(n), getFirstRecord(), and getLastRecord() Java code methods throw an exception when they are invoked if Select Next Record is set to Shuffle Records or Randomly.

  5. The getRecord(n), getFirstRecord(), and getLastRecord() Java code methods throw an exception if they are invoked and the databank is not indexed.

  6. Use Seed is only available when Select Next Record is set to Shuffle Records or Randomly.

  7. A specific databank range and starting index may not be set if the databank cannot be indexed.

  8. The Select Next Record: Shuffle Records and Randomly options are only allowed when the databank can be indexed.

  9. The Select Next Record: Shuffle Records is only allowed when the databank can be indexed and when there are fewer than 200,000 records.

2.8.4.2 Using Very Large Databanks

If you want to use an extremely large databank (for example, records in the millions), use the follow procedure:

  1. Make sure the script does not use these databanking methods in the script code:

    getRecordNumber() 
    getFirst() 
    getLast() 
    getRecord(n)
    
  2. Set the Databank Setup Timeout to a very small value, for example, 1 second.

    1. Select OpenScript Preferences from the View menu.

    2. Select General in the preferences.

    3. Set Databank Setup Timeout to 1 (sec).

  3. Set the databank setting to Sequential mode.

    1. Select Iterate from the Script menu.

    2. Make sure Select Next Record is set to "Sequentially".

  4. Save the script and playback in Oracle Load Testing. The index preparation will timeout (expected). Although the index will not be generated, Oracle Load Testing will still be able to run with the databank using Sequential mode and deliver records to Virtual users.

2.9 Using Data Tables

Data Table is a script service that allows users to use an Excel file as a data input and output for scripts. The Data Table is a spreadsheet-like data table for Functional testing scripts. As a script service, a Data Table exists only during script playback. If you need to persistant data from the Data Table, the data can be saved to an Excel file. While Excel file data can be imported and exported to and from a Data Table, the OpenScript Data Table is not as robust as Excel in handling custom formats. The Data Table is primarily used for data manipulation. To avoid format incompatibilities you should use only basic formats like General and String. Use Numeric and Date format only if absolutely needed.

There are two versions of the Data Table: the view/edit Data Table and the runtime Data Table. The view/edit Data Table can be accessed using the Data Table option on the View menu. The view/edit Data Table tab appears in the tab views of the OpenScript main window. The view/edit Data Table content can be changed by manually inputting data into cells or by importing an Excel file before playback.

The Data Table API provides methods for accessing the data in the Data Table programmatically within functional test scripts during playback of a script.

When you play back a script and select the results in the Results view, the Details view includes a Result Data Table tab that shows the runtime Data Table resulting from the playback of the script. Changes made to the runtime Data Table during script playback do not appear in the view/edit Data Table. The Result Data Table can be exported to an Excel file to view the changes.

The following sections explain how to use Data Tables within functional test scripts.

2.9.1 Enabling the Data Table Service

The Data Table Service provides programmatic access to data stored in a Data Table using the Data Table API. The Data Table service must be enabled to provide access to the Data Table view and the runtime Data Table.

To enable the Data Table Service:

  1. Record a functional test script.

  2. Select Script Properties from the Script menu.

  3. Select Modules.

  4. Select the Data Table option and click OK.

    In the Java Code view, the datatable service is added to the script code as follows:

    @ScriptService oracle.oats.scripting.modules.datatable.api.DataTableService datatable;
    
  5. Select Data Table from the View menu to show the view/edit Data Table tab view. The runtime Data Table is accessed using the Data Table API.

2.9.2 Setting the First Row Policy

The First Row policy specifies how the data in the first row of the Data Table will be used. The first row policy should be set before any data is manipulated within a Data Table sheet. The first row policy is important because Data Tables and Excel differ in the use of data as column headers. Data Tables can use the first row of data as column headers. Excel files use fixed indexes (for example, A, B, C) as the column headers. If your script manipulates data and columns in a Data Table during script playback, how the columns are referenced is important. For example, if you add a column in an Excel file, the new column inserts into the sheet essentially moving the current data to be under a different column header. If a new column is added before column C, the new column is inserted as column C and the data that was under column C is now under column D. If you add a column in a Data Table and the first row policy is not to use the first row of data as the column header, the Data Table will perform the same as an Excel file. However, if the first row policy is set to use the first row of data as the column header, the inserted column will have a new column header inserted, and the existing data will still be under the same column header as before the new column was added. If your script imports and exports the manipulated data from a Data Table to and from an Excel file, the first row policy will affect how the data is referenced.

To set the first row policy, right-click in the Data Table view and select Use First Row as Column Header. The data values in the first row of the table move up into the table header as column names.

In the Java Code view, the first row policy for each Data Table sheet is set using the useFirstRowAsColumnHeader() method, as follows:

datatable.useFirstRowAsColumnHeader("Sheet1");

2.9.3 Importing Data from a Spreadsheet File

Data can be loaded into a Data Table from an Excel spreadsheet file.

Note:

Excel restricts sheet names to 31 characters. Other spreadsheet applications may allow longer sheet names. The Data Table conforms to the Excel restrictions. If a sheet name is longer than the 31 character restriction, then the Data Table truncates the length of name to 31 characters. Any illegal characters, such as colon (:), backslash (\), asterisk (*), question mark (?), forward slash (/) ,opening square bracket ([) losing square bracket (]), will be substituted with the underscore (_) character.

To load data from an Excel spreadsheet file:

  1. Enable the Data Table service for the functional test script.

  2. In the Java Code view, add the importSheet() method, as follows:

    datatable.importSheet("C:\\OracleATS\\Book1.xls", "Sheet1", "Sheet1", false);
    

2.9.4 Exporting Data to a Spreadsheet File

Data in a Data Table can be exported to an Excel spreadsheet file.

To Export data from a Data Table to an spreadsheet file:

  1. Enable the Data Table service for the functional test script and show the Data Table view.

  2. In the Java Code view, add the exportSheet() method, as follows:

    datatable.exportSheet("C:\\OracleATS\\Book1.xls", "Sheet1", "Sheet1", 
      ExportMode.CREATE);
    

    When exporting Data Tables to Excel files, you can set the export policy: Create or Merge. Create will completely recreate the destination file. The resulting file will contain only the exported sheets from the Data Table. Merge will add exported sheets to the existing file, overwriting existing sheets only if the sheet is named as an exported sheet from the Data Table.

2.9.5 Changing Data During Script Playback

The runtime Data Table content can be changed during script playback in the following ways:

  • manually when playback is paused by a breakpoint

  • manually when playback is paused by an exception

  • manually when playback is paused using the Pause toolbar button

  • programmatically at runtime using the datatable API

Changes to the runtime Data Table can be saved can be saved to the script's session result folder during script playback using the datatable.save method. The view/edit Data Table and Result Data Table can be exported to an Excel file.

The following sections provide examples of how to change data in the runtime Data Table programmatically using the datatable API.

2.9.5.1 Getting and Setting Cell Values

You can use the datatable API to get and set Data Table values programmatically during playback of a script. The following examples show how to get and set values using the datatable API getValue() and setValue() methods. Data table rows are 0 based. Cell A1 in the data table is accessed by datatable.getValue(0, "A").

2.9.5.1.1 Getting Data by Row and Column Value

The following example script code retrieves the value in the cell at row 1, column A of the current worksheet and prints the value to the Results view:

String cellValue1 = datatable.getValue(0, "A").toString();
info(cellValue1); 
2.9.5.1.2 Getting Data by Sheet, Row, and Column Value

The following example script code retrieves the value in the cell at row 1, column A of the worksheet named "Sheet1" and prints the value to the Results view:

String cellValue2 = datatable.getValue("Sheet1", 0, "A").toString();
info("cell value = " + cellValue2);
2.9.5.1.3 Setting Data by Row and Column Value

The following example script code sets the value in the cell at row 1, column A to a boolean value of true:

datatable.setValue(0, "A", true);

The following example script code sets the value in the cell at row 1, column A to a double value of 10.5:

datatable.setValue(0, "A", 10.5);

The following example script code sets the value in the cell at row 1, column A to a String value of myString:

datatable.setValue(0, "A", "myString");
2.9.5.1.4 Setting Data by Sheet, Row, and Column Value

The following example script code sets the value in the cell at row 1, column A of "Sheet1" to a boolean value of true:

datatable.setValue("Sheet1", 0, "A", true);

The following example script code sets the value in the cell at row 1, column A of "Sheet1" to a double value of 10.5:

datatable.setValue("Sheet1", 0, "A", 10.5);

The following example script code sets the value in the cell at row 1, column A of "Sheet1" to a String value of myString:

datatable.setValue("Sheet1", 0, "A", "myString");

2.9.5.2 Adding and Deleting Rows and Columns

You can use the datatable API to add and delete Data Table rows and columns programmatically during playback of a script. The following examples show how to add and delete rows and columns using the datatable API addColumn(), deleteColumn(), insertRow(), and deleteRow() methods.

2.9.5.2.1 Adding Columns

The following example script code adds a new column named New Column to the current worksheet after the last column in the worksheet:

datatable.addColumn("New Column");

The following example script code adds a new column named New Column to the current worksheet before the column with an index value of 0:

datatable.addColumn("New Column", 0);

The following example script code adds a new column named New Column to the worksheet named "Sheet1" after the last column in the worksheet:

datatable.addColumn("Sheet1", "New Column");

The following example script code adds a new column named New Column to the worksheet named "Sheet1" before the column with an index value of 0:

datatable.addColumn("Sheet1", "New Column", 0);
2.9.5.2.2 Deleting Columns

The following example script code deletes the column named A from the current worksheet:

datatable.deleteColumn("A");

The following example script code deletes the column named A from the current worksheet named "Sheet1":

datatable.deleteColumn("Sheet1", "A");
2.9.5.2.3 Adding Rows

The following example script code adds a new row to the current worksheet before the row with an index value of 0:

datatable.insertRow(0);

The following example script code adds a new row to the worksheet named "Sheet1" before the row with an index value of 0:

datatable.insertRow("Sheet1", 0);
2.9.5.2.4 Deleting Rows

The following example script code deletes the row before the row with an index value of 1 from the worksheet named "Sheet1":

datatable.deleteRow("Sheet1", 1);

2.9.5.3 Adding and Deleting Worksheets

You can use the datatable API to add and delete worksheets programmatically during playback of a script. The following examples show how to add and delete worksheets using the datatable API addSheet() and deleteSheet() methods.

2.9.5.3.1 Adding Worksheets

The following example script code adds a new worksheet named "Sheet1" to the Data Table:

datatable.addSheet("Sheet1");

The following example script code adds a new worksheet named "Sheet1" to the Data Table before "Sheet2":

datatable.addSheet("Sheet1", "Sheet2");
2.9.5.3.2 Deleting Worksheets

The following example script code deletes the worksheet named "Sheet1" from the Data Table:

datatable.deleteSheet("Sheet1");

2.9.5.4 Getting Worksheet, Row, and Column Counts

You can use the datatable API to get sheet, row, and column counts programmatically during playback of a script. The following examples show how to get sheet, row, and column counts using the datatable API getSheetCount(), getRowCount(), and getColumnCount()methods.

2.9.5.4.1 Getting Worksheet Counts

The following example script code gets the sheet count from the Data Table and prints the value to the Results view:

int sheetCount = datatable.getSheetCount();
info("Sheet count = " + sheetCount);
2.9.5.4.2 Getting Row Counts

The following example script code gets the row count from the current worksheet and prints the value to the Results view:

int rowCount = datatable.getRowCount();
info("row count = " + rowCount);

The following example script code gets the row count from the worksheet named "Sheet1" and prints the value to the Results view:

int rowCount1 = datatable.getRowCount("Sheet1");
info("row count Sheet1 = " + rowCount1);
2.9.5.4.3 Getting Column Counts

The following example script code gets the column count from the worksheet named "Sheet1" and prints the value to the Results view:

int columnCount = datatable.getColumnCount("Sheet1");
info("column count Sheet1 = " +columnCount);

The following example script code gets the column count from the worksheet with an index of 0 and prints the value to the Results view:

int columCount0 = datatable.getColumnCount(0);
info("column count Sheet index 0 = " + columnCount);

2.9.5.5 Getting the Current Sheet and Row

You can use the datatable API to get the current sheet, row, and column programmatically during playback of a script. The following examples show how to get the current sheet, row, and column using the datatable API getCurrentSheet() and getCurrentRow() methods.

2.9.5.5.1 Getting the Current Sheet

The following example script code gets the name of the current sheet from the Data Table and prints the value to the Results view:

String currentSheet = datatable.getCurrentSheet();
info("Current Sheet = " + currentSheet)
2.9.5.5.2 Getting the Current Row

The following example script code gets the current row from the current worksheet and prints the value to the Results view:

int currentRow = datatable.getCurrentRow();
info("Current row = " + currentRow);

2.9.5.6 Setting Next and Previous Rows

You can use the datatable API to set the next and previous row programmatically during playback of a script. The following examples show how to set the next and previous rows using the datatable API setNextRow() and getCurrentRow() methods.

2.9.5.6.1 Setting the Next Row

The following example script code sets the next row of the current sheet in the Data Table:

datatable.setNextRow();
2.9.5.6.2 Setting the Previous Row

The following example script code sets the previous row of the current sheet in the Data Table:

datatable.setPreviousRow();

2.9.5.7 Importing and Exporting Documents and Sheets

You can use the datatable API to get the import and export spreadsheet documents and worksheets programmatically during playback of a script. The following examples show how to import and export spreadsheet files and worksheets using the datatable API importExcel(), importSheet(), exportToExcel() and exportSheet() methods.

2.9.5.7.1 Importing an Excel Spreadsheet Document

The following example script code imports the myXls.xls Excel spreadsheet document into the Data Table:

datatable.importExcel("c:\\myXls.xls");
2.9.5.7.2 Importing Worksheets

The following example script code imports the single worksheet named "SourceSheet" from the myXls.xls Excel spreadsheet document and adds it to the Data Table with the name "DestinationSheet":

datatable.importSheet("c:\\myXls.xls", "SourceSheet", "DestinationSheet");

The following example script code imports all worksheet from the myXls.xls Excel spreadsheet document and adds them to the Data Table overwriting any sheets with the same names:

datatable.importSheets("c:\\myXls.xls", true);

The following example script code imports the specified list of worksheets from the myXls.xls Excel spreadsheet document and adds them to the Data Table overwriting any sheets with the same names:

import java.util.List;
import java.util.ArrayList;
//[...]
List<String> sheetList = new ArrayList<String>();
sheetList.add("Sheet1");
sheetList.add("Sheet2");
datatable.importSheets("c:\\myXls.xls", sheetList, true);

The following example script code imports the specified list of worksheets from the myXls.xls Excel spreadsheet document and adds them to the Data Table overwriting any sheets with the same names using the first row:

import java.util.List;
import java.util.ArrayList;
//[...]
List<String> sheetList = new ArrayList<String>();
sheetList.add("Sheet1");
sheetList.add("Sheet2");
datatable.importSheets("c:\\myXls.xls", sheetList, true, true);
2.9.5.7.3 Exporting an Excel Spreadsheet Document

The following example script code exports the myXls.xls Excel spreadsheet document from the Data Table to a file:

datatable.exportToExcel("c:\\myXls.xls");
2.9.5.7.4 Exporting Worksheets

The following example script code exports the single worksheet named "SourceSheet" from the Data Table to the myXls.xls Excel spreadsheet document with the name "DestinationSheet":

datatable.exportSheet("c:\\myXls.xls", "SourceSheet", "DestinationSheet");

The following example script code imports all worksheet from the myXls.xls Excel spreadsheet document and adds them to the Data Table overwriting any sheets with the same names:

datatable.importSheets("c:\\myXls.xls", true);

The following example script code exports the specified list of worksheets from the Data Table to the myXls.xls Excel spreadsheet document:

import java.util.List;
import java.util.ArrayList;
//[...]
List<String> sheetList = new ArrayList<String>();
sheetList.add("Sheet1");
sheetList.add("Sheet2");
datatable.exportSheets("c:\\myXls.xls", sheetList);

2.9.5.8 Using Data Tables with Parent and Child Scripts

You can use the datatable API to change data in the Data Table of a parent script that runs a child script programmatically during playback of parent and child scripts. The following examples show how to change data in parent scripts from child scripts using the datatable API getParentDatatable() and getGlobalDatatable() methods.

2.9.5.8.1 Accessing the Parent Data Table from a Child Script

The following example script code shows how a child script can access and change data in the Data Table of the parent script. Both the parent and child scripts must have the Data Table service enabled. It is important that it always should be verified that the return value is not null. In the child script, make sure the Data Table service is enabled and create a parent Data Table instance:

import oracle.oats.scripting.modules.datatable.api.DataTableService;
//[...]
DataTableService parentDatatable = datatable.getParentDatatable();
  if(parentDatatable != null) 
   {
      info("set parent datatable value");
      parentDatatable.setValue(0,"A", 30);
      parentDatatable.save(); 
   }

In the parent script, run the child script using the getScript("alias").run() method:

getScript("childScript").run(1);

The Data Table results appear in the parent script Results and the Results Data Table of the Details view.

2.9.5.8.2 Accessing the Top-Most Data Table in Chain of Parent Scripts

The following example script code shows how a child script can access and change data in the top-most Data Table in a chain of parent scripts. All scripts in the chain must have the Data Table service enabled. In the child script, make sure the Data Table service is enabled and create a global Data Table instance:

import oracle.oats.scripting.modules.datatable.api.DataTableService;
//[...]
DataTableService globalDatatable = datatable.getGlobalDatatable(); 
info("set global datatable value"); 
globalDatatable.setValue(0, "B", 20);
globalDatatable.save();

If the script containing this code is run as a stand alone script the return value is a datatable of the script itself.

2.10 Using the Shared Data Service

This section describes how to enable and use the Shared Data Service.

2.10.1 Basic Scenarios

The following are the basic scenarios for using the Shared Data Service:

  • Queue Mode: Items are stored sequentially in queues. Scripts can get the first or last data item in the queue. Other items cannot be accessed randomly.

    Script A is run by 100 Virtual Users, which act as message producers putting message objects to the shared data queues.

    Script B is run by another 100 Virtual Users, which act as consumers getting message objects from the shared data queues.

    Consumer Virtual Users can get an object from the beginning or end and the information from a queue. If the queue is empty, the consumer Virtual User is blocked until the timeout is reached. Once the object can be retrieved, the consumer Virtual User is resumed.

  • Hash Map mode: Any item can be accessed using a key. The hash map may already contain a mapping for a key. The hash map needs to be checked before a new item is put into a hash map.

    Script A is run by 100 Virtual Users, which put key-value objects to a shared data hash map.

    Script B is run by another 100 Virtual Users, which get values with keys from the shared data hash map.

    If a Virtual User cannot get the value to which the specified key is mapped, it will be blocked until the timeout is reached or the key-value is added to the map.

2.10.2 Enabling the Shared Data Service

To enable the Shared Data Service:

  1. Start OpenScript.

  2. Open an existing script or create and record a new script.

  3. Select Script Properties from the Script menu.

  4. Select the Modules category.

  5. Select the Shared Data module.

  6. Click OK. The Shared Data Service will be added to the script class in the Java Code as follows.

    @ScriptService oracle.oats.scripting.modules.sharedData.api.SharedDataService sharedData;
    

    Once you have enabled the Shared Data service, you can set the password encryption and the connection parameters and then use the Shared Data API to manipulate message queues or hash maps. See Section 2.7.5, "Setting the Password Encryption" for additional information about setting the encryption password. You use the sharedData class in the Java code view to create manipulate message queues and hash maps.

2.10.3 Setting the Connection Parameters

The connection parameters specify the Oracle Load Testing server to use for the Shared Data Service and the authentication settings. During a load test, the Shared Data Service is limited to running only on the Oracle Load Testing controller running the test. To set the connection parameters:

  1. Make sure the Shared Data Service is enabled and the password encryption is specified as previously described.

  2. Select the script node where you want to set the connection parameters.

  3. Select Add from the Script menu and then select Other.

  4. Expand the Shared Data folder.

  5. Select Set Connection Parameters and click OK.

  6. Set the connection parameters as follows:

    Address: Specify the address of the machine to use for the Shared Data Service. For example: t3://localhost:8088 or t3://machinename.com:8088.

    User Name: Specify the user name to use for authentication. The default name is oats unless changed in the Oracle Application Testing Suite configuration.

    Password: Specify the password to use for authentication.

  7. Click OK. A Connection Parameters node will be added to the script tree.

  8. In the Java Code view, the Connection Parameters consist of the code executed in the sharedData.setConnectionParameters procedure:

    sharedData.setConnectionParameters("t3://localhost:8088", "oats",
      decrypt("L4I57b+KpnI2BQSRKPG88w=="));
    

After setting the connection parameters, you can user the Shared Data API in the Java Code view to manipulate data in message queues and hash maps.

2.10.4 Creating a Shared Data Queue

To create a shared data queue:

  1. Create an script project.

  2. Make sure the Shared Data Service is enabled, the password encryption, and connection parameters are specified as previously described.

  3. Open the Java Code view and insert the sharedData.createQueue code with a life time value into the script where you want to create the queue, as follows:

    info("Create queueA with life time of 10 minutes");
    sharedData.createQueue("queueA", 10);
    

    The maximum number of queues is 1000. The maximum capacity of a queue is 65535. If the maximum is exceeded, an exception occurs. Once the life time expires, the queue is destroyed.

2.10.5 Inserting Data into a Shared Data Queue

The types of the "values" that can be put into a queue are as follows:

  • String

  • boolean

  • integer

  • long

  • double

  • float

  • a List of any of the above data types

  • User-defined serializable java objects.

To insert data into an existing queue:

  1. Set up the shared data service and create a queue as previously described.

  2. Open the Java Code view and insert the sharedData.offerFirst or sharedData.offerLast code with a value into the script where you want to insert data into the queue, as follows:

    int iterationNum = getIteration().getTotalIterationsCompleted() + 1;
    info("Insert data at the front of an existing queueA");
    sharedData.offerFirst("queueA", "first" + iterationNum);
    

    or

    int iterationNum = getIteration().getTotalIterationsCompleted() + 1;
    info("Insert data at the end of an existing queueA");
    sharedData.offerLast("queueA", "last" + iterationNum);
    
    info("parameter type - String");
    sharedData.offerFirst("queueA", "value");
    
    info("parameter type - list of Strings");
    ArrayList<String> listOfStr = new ArrayList<String>();
    listOfStr.add(0, "val1");
    listOfStr.add(1, "val2");
    sharedData.offerFirst("queueA", listOfStr);
    ArrayList<String> queueValue = (ArrayList<String>) 
       sharedData.pollFirst("queueA");
    
    info("parameter type - boolean");
    sharedData.offerFirst("queueA", true);
    
    info("parameter type - int");
    sharedData.offerFirst("queueA", 10);
    
    info("parameter type - double");
    sharedData.offerFirst("queueA", 10.5);
    
    info("parameter type - long");
    sharedData.offerFirst("queueA", 100);
    

2.10.6 Getting Data from a Shared Data Queue

To get data from a queue:

  1. Set up the shared data service, create a queue, and insert data to the queue as previously described.

  2. Open the Java Code view and insert the Shared Data method(s) to use to get data into the script where you want to get data from the queue. The Shared Data Service includes methods for getting the length and peeking (gets the data) and polling (gets and removes the data) data, as follows:

    info("Get the length of queueA");
    int actualLength = sharedData.getLengthOfQueue("queueA");
    
    info("Get the most current item of queueA");
    String queueValue1 = (String) sharedData.peekFirst("queueA");
    
    info("Get the most current item of queueA - timeout after 5 seconds");
    String queueValue2 = (String) sharedData.peekFirst("queueA", 5000);
    
    info("Get the oldest item of queueA");
    String queueValue1 = (String) sharedData.peekLast("queueA");
    
    info("Get the oldest item of queueA - timeout after 5 seconds");
    String queueValue2 = (String) sharedData.peekLast("queueA", 5000);
    
    info("Get and remove the most current item from queueA");
    String pollValue1 = (String) sharedData.pollFirst("queueA");
    
    info("Remove the most current item from queueA - Timeout after 5 seconds");
    String pollValue2 = (String) sharedData.pollFirst("queueA", 5000);
    
    info("Remove the oldest item from queueA");
    String pollValue1 = (String) sharedData.pollLast("queueA");
    
    info("Remove the oldest item from queueA - Timeout after 5 seconds");
    String pollValue2 = (String) sharedData.pollLast("queueA", 5000);
    
    info("Waiting for an existing value 100 in queueA");
    boolean isFound1 = sharedData.waitFor("queueA", 100);
    
    info("Waiting for an existing value 100 in queueA - timeout afer 5 seconds");
    boolean isFound2 = sharedData.waitFor("queueA", 100, 5000);
    
  3. Add other custom code to the script to use the data from the queue.

2.10.7 Clearing a Shared Data Queue

Clear queues when the script is finished using the data.

To clear a shared data queue:

  1. Open the Java Code view and insert the sharedData.clearQueue code with a the name of the queue to clear into the script where you want to clear the queue, as follows:

    info("Clear queueA");
    sharedData.clearQueue("queueA");
    

2.10.8 Destroying a Shared Queue

Destroy queues when the script is finished using the data. Destroying queues releases the queues' data and its listeners and release the memory that is allocated to a queue.

To destroy a shared data queue:

  1. Open the Java Code view and insert the sharedData.destroyQueue code with a the name of the queue to destroy into the script where you want to destroy the queue, as follows:

    info("Destroy queueA");
    sharedData.destroyQueue("queueA");
    

2.10.9 Creating a Shared Data Hash Map

To create a shared data hash map:

  1. Create an script project.

  2. Make sure the Shared Data Service is enabled, the password encryption, and connection parameters are specified as previously described.

  3. Open the Java Code view and insert the sharedData.createMap code with a life time value into the script where you want to create the hash map, as follows:

    info("Create mapA with life time of 10 minutes");
    sharedData.createMap("mapA", 10);
    

    The maximum number of hash maps is 1000. The maximum capacity of a hash map is 65535. If the maximum is exceeded, an exception occurs. Once the life time expires, the hash map is destroyed.

2.10.10 Inserting Data into a Shared Data Hash Map

The types of the "values" that can be put into a hash map are the same as for queues. See Section 2.10.5, "Inserting Data into a Shared Data Queue" for a list of the data types.

To insert data into an existing hash map:

  1. Set up the shared data service and create a hash map as previously described.

  2. Open the Java Code view and insert the sharedData.putToMap code with a key and value into the script where you want to insert data into the hash map, as follows:

    int iterationNum = getIteration().getTotalIterationsCompleted() + 1;
    info("put key/value pair to an existing mapA");
    sharedData.putToMap("mapA", "key" + iterationNum, "value" + iterationNum);
    
    info("parameter type - String");
    sharedData.putToMap("mapA", "key", "value");
    String mapValue = (String) sharedData.getFromMap("mapA", "key");
    
    info("parameter type - list of Strings");
    ArrayList<String> listOfStr = new ArrayList<String>();
    listOfStr.add(0, "val1");
    listOfStr.add(1, "val2");
    sharedData.putToMap("mapA", "key", listOfStr);
    ArrayList<String> mapVal = (ArrayList<String>) sharedData.getFromMap("mapA", 
       "key");
    
    info("parameter type - boolean");
    sharedData.putToMap("mapA", "key", true);
    
    info("parameter type - int");
    sharedData.putToMap("mapA", "key", 10);
    
    info("parameter type - double");
    sharedData.putToMap("mapA", "key", 10.5);
    
    info("parameter type - long");
    sharedData.putToMap("mapA", "key", 100);
    

2.10.11 Getting Data from a Shared Data Hash Map

To get data from a hash map:

  1. Set up the shared data service, create a queue, and insert data to the hash map as previously described.

  2. Open the Java Code view and insert the Shared Data method(s) to use to get data into the script where you want to get data from the hash map. The Shared Data Service includes methods for getting the keys of the hash map and getting data and removing data from the hash map, as follows:

    info("Get all keys of mapA");
    String [] lsKey = sharedData.getKeysOfMap("mapA");
    
    info("Get key/value pair from mapA");
    String actualValue = (String) sharedData.getFromMap("mapA", "key");
    
    info("Get key/value pair from mapA - timeout after 5 seconds");
    String actualValue1 = (String) sharedData.getFromMap("mapA", "key", 5000);
    
    info("Remove key/value pair from mapA");
    String removeValue = (String) sharedData.removeFromMap("mapA", "key");
    
    info("Remove key/value pair from mapA - timeout after 5 seconds");
    String removeValue1 = (String) sharedData.removeFromMap("mapA", "key", 5000);
    
  3. Add other custom code to the script to use the data from the hash map.

2.10.12 Clearing a Shared Data Hash Map

Clear hash maps when the script is finished using the data.

To clear a shared data hash map:

  1. Open the Java Code view and insert the sharedData.clearMap code with a the name of the map to clear into the script where you want to clear the hash map, as follows:

    info("Clear mapA");
    sharedData.clearMap("mapA");
    

2.10.13 Destroying a Shared Data Hash Map

Destroy hash maps when the script is finished using the data. Destroying hash maps releases the map's data and its listeners and release the memory that is allocated to a map.

To destroy a shared data hash map:

  1. Open the Java Code view and insert the sharedData.destroyMap code with a the name of the map to destroy into the script where you want to destroy the hash map, as follows:

    info("Destroy mapA");
    sharedData.destroyMap("mapA");
    

2.11 Using The Utilities API

You can use the utilities API to read values from text files including CSV and XML. The following sections explain how to use the utilities API.

2.11.1 Working with Text Files

The Utilities API includes a getFileService()object with methods for working with text files such as reading lines of text from a file or appending to a file. The following examples show some ways to use getFileService.

To add code that reads text from a file:

  1. Create a script project.

  2. Open the Java Code view.

  3. Add the readLines() method to specify the file to read. The following example shows how to parse the lines of text in a file and print to the OpenScript console view:

    import java.io.File;
    //[...]
    String[] lines = utilities.getFileService().readLines("C:/Sample.txt");
    for (String line : lines) {
    info(line);
    }
    

To add code that appends text to a file:

  1. Create a script project.

  2. Open the Java Code view.

  3. Add the appendStringToFile() method to specify the file to which to append text strings. The following example shows how to create a new file and append lines of text to the file:

    import java.io.File;
    //[...]
    utilities.getFileService().createDestinationFile("myFile.txt", false);
    String line1 = "This is a new line 1";
    String line2 = "This is a another new line 2";
    String contents = "\n" + line1 + "\n" + line2;
    utilities.getFileService().appendStringToFile("myFile.txt", contents);
    

2.11.2 Working with CSV Files

The Utilities API includes a loadCSV() object for working with data from a Comma Separated Value text file.

To add code that loads and prints data from a .CSV file:

  1. Create a script project.

  2. Open the Java Code view.

  3. Add the loadCSV method to specify the file to read. For this example the file, "C:\customer.csv" contains this data:

    FirstName,LastName,MiddleInitial
    John,James,R
    Mary,Simpson,J
    

    The following example shows one way to parse a table of text in a .CSV file and print values to the OpenScript console view:

    import java.io.File;
    import java.util.List;
    //[...]
    String filePath = "c:\\";
    String csvFile = filePath + "fmstocks_data.csv";
    File file = new File(csvFile);
    
    Table table = utilities.loadCSV(csvFile);
    
    //Print the CSV file
    String columns = "";
    int columnNumber = table.getColumns().getColumnCount();
    String [] columnNames = table.getColumns().getColumnNames();
    for (int index=0; index<columnNumber; index++)
       columns += columnNames[index] + "  ";
    info(columns);
    
    List <Row> rows = table.getRows();
    for (int index=0; index<rows.size(); index++) {
        String [] rowValue = rows.get(index).getAll();
        String rowContent = "";
        for (int columnIndex=0; columnIndex<rowValue.length; columnIndex++)
            rowContent += rowValue[columnIndex] + "  ";
        info(rowContent);
    }
    

2.11.3 Working with XML Files

The Utilities API includes a loadXML() object for reading text from a XML formatted text file.

To add code that reads text from a .XML file:

  1. Create a script project.

  2. Open the Java Code view.

  3. Add the loadXML method to specify the file to read. For this example the file, "C:\grocery.xml" contains this data:

    <?xml version="1.0" encoding="utf-8"?>
    <Oceans>
      <ocean name="Arctic"/>
      <ocean name="Atlantic"/>
      <ocean name="Indian"/>
      <ocean name="Pacific"/>
      <ocean name="Southern"/>
    </Oceans>
    

    The following example shows how to parse a table of text in a .XML file and print values to the OpenScript console view:

    XML xml = utilities.loadXML("C:/oceans.xml");
    XML root = xml.getChildren()[0];
    info(root.getTagName());
    XML[] oceans = root.getChildren();
    
    for (XML ocean : oceans){
    info(ocean.getAttribute("name"));
    }
    

2.11.4 Getting Values from a Database

Getting values from a database requires a database definition, a database SQL query or SQL execute and a disconnect from the database. This section explains how to manually add database actions to a script. See the Oracle OpenScript User's Guide for additional information about importing a DBReplay capture file or SQL statements from a plain SQL and PL/SQL statements .SQL script file to generate an OpenScript load testing script.

To get values from a database:

  1. Create a database script project.

  2. Select the node where you want to add the database definition.

  3. Select the Script menu and then select Other from the Add sub menu.

  4. Expand the Database node and select Database Definition.

  5. Click OK.

  6. Specify the database definition information.

    Database Driver - specify the database driver to use.

    • Oracle Thin (oracle.jdbc.driver.OracleDriver) - when selected, the database connection uses the Oracle Thin database driver. Specify the following connection information:

      Hostname - specify the name of the host machine on which the database is located.

      Port - specify the port number to use.

      • SID - when selected, specify the System ID to identify the particular database on the system.

      • Service Name - when selected, specify the Service Name defined as the alias for the database instance.

    • ODBC (sun.jdbc.odbc.JdbcOdbcDriver) - when selected, the database connection uses the ODBC database driver. Specify the following connection information:

      Data source - specify the name of the ODBC data source to which to connect.

    URL - specify the URL to use to access the database.

    Username - specify a user name to log into the database.

    Password - specify a password to log into the database.

    Alias - specify an alias name to use to identify the database definition. The alias appears in the script tree for the definition and is selected when adding database actions to the script.

    Test - test the connection to the database based upon the specified driver and database information.

  7. Click Test to verify a successful connection.

  8. Click OK.

  9. Select the node where you want to add the database connection. The OpenScript database connect method is optional. The database connect is invoked automatically when calling execute or query methods

  10. Select the Script menu and then select Other from the Add sub menu.

  11. Expand the Database node and select Connect.

  12. Select the database alias and click OK.

  13. Select the node where you want to add the database query or execute statement.

  14. Select the Script menu and then select Other from the Add sub menu.

  15. Expand the Database node and select SQL Query or SQL Execute.

  16. Specify the SQL statement to query or execute and click Add.

  17. Specify a data type and define a name for the parameter.

  18. Click OK.

  19. Click OK.

  20. Select the node where you want to add the database disconnect.

  21. Select the Script menu and then select Other from the Add sub menu.

  22. Expand the Database node and select Disconnect.

  23. Select the database alias and click OK.

    In the Java Code view, the utilities.getSQLService() methods will be added to the script code for each database script action (additional code and comments added):

    //define database
    utilities.getSQLService().define("oracledb",
       "oracle.jdbc.driver.OracleDriver", "00.000.000.000", "myuserID",
       decrypt("ZgEQLMIUx8EVDAhfAenvyg=="));
    
    //connect to database
    utilities.getSQLService().connect("oracledb");
    
    //execute SQL statement
    String query = "Create table Employee (ID number(4) not null unique, " +
    "FirstName varchar2(40) not null, LastName varchar2(40) not null, " +
    "Country varchar2(40), HireDate date)";
    info("Query: " + query);
    utilities.getSQLService().execute("oracledb", query);
    
    //execute update SQL statement
    query = "Insert into Employee (ID, FirstName, LastName, Country, HireDate) " + 
       "Values (101, 'Tom', 'Smith', 'USA', '01-JAN-95')";
    utilities.getSQLService().executeUpdate("oracledb", query);
    
    //query SQL statement
    query = "Select * from Employee";
    Table table = utilities.getSQLService().query("oracledb", query);
    
    //print table
    for (int i=0; i<table.getRowCount(); i++) {
       Row row = table.getRow(i);
       String [] rowValue = row.getAll();
       String rowContent = "";
       for (int col=0; col<rowValue.length; col++)
          rowContent += rowValue[col] + "  ";
       info(rowContent);
    }
    
    //disconnect from database
    utilities.getSQLService().disconnect("oracledb");
    

2.11.4.1 Adding a SQL Query Test

A SQL Query test can be used to test data values retrieved from a database using a SQL query against expected values.

To add a SQL Query test:

  1. Create a database script project.

  2. Select the node where you want to add the SQL Query test.

  3. Select the Script menu and then select Other from the Add sub menu.

  4. Expand the Database node and select SQL Query.

  5. Click OK.

  6. If you have already created a database connection, select the database alias. If you have not already created a database connection, click New and specify a new database definition. See Section 2.11.4, "Getting Values from a Database" for additional information about creating a database definition.

  7. Enter a SQL Statement to use to define the data to retrieve from the database.

  8. Click Test to verify the data is retrieved from the database. If the Test Results dialog does not appear listing the data from the SQL Statement, verify the SQL Statement is correctly structured.

  9. Click Close to close the Test Results dialog box.

  10. Click Create SQL Query Test.

  11. Enter a name for the test.

  12. Set the Verify only, never fail option.

  13. Select the Test Data option:

    • Entire Table - when selected, the entire table of data retrieved from the SQL Statement is included in the test.

    • Filter table by query- when selected, only the data that matches the filter query is included in the test. Enter a SQL query and click Apply to apply the filter to the test data.

    • Apply - applies the query filter to the test data.

  14. Enable testing on specific data values by selecting or clearing the check boxes in each cell. Click Enable All to enable testing on all data values in the grid. Click Disable All to disable testing on all data values in the grid, then select individual cells manually.

    • [Row] - shows the row number of the test data.

    • [Table column name(s)] - shows the name(s) of the database table field(s) retrieved from the database by the SQL Statement. Each column in the SQL Query Test will show table field names as the column headers. Select the check box to enable testing or clear the check box to disable testing on specific data values.

  15. For each selected table cell, specify the SQL Query Test Details:

    SQL Query Test Details - shows the test details for the selected table cell.

    • Value from DB - shows the actual value of the data retrieved from the database for the selected table cell.

      Enable - when selected, testing for the selected cell is enabled.

    • Cell - shows the row and column information for the selected table cell.

      Row - the row number of the selected table cell.

      Column Name - the column name of the selected table cell. This is the field name retrieved from the database.

    • Value Type - specifies the data type for the value in the selected table cell.

    • Operator - specifies the test operator used to compare the data value in the selected table cell against the expected value.

    • Expected Value - specifies the expected value to compare against the value retrieved from the database.

      Substitute Variable - opens a dialog box for selecting a script variable to use for the Expected Value.

  16. Click OK when finished. New Query and Query Test nodes will be added to the script tree.

    In the Java Code view, the utilities.getSQLService() methods will be added to the script code for the database query and SQL test:

    utilities.getSQLService().query(9, "mydb", "Select FName from Employee", null);
    {
    utilities.getSQLService().assertQuery(
       null, "mySQLtest", null,
       utilities.getSQLService().cell(1, "FNAME",
          "Aaron", SQLTestOperator.StringExact),
       utilities.getSQLService().cell(2, "FNAME",
          "Adrian",SQLTestOperator.StringExact)));
    }
    

    When you play back the script, the test results appear in the Results view.

2.11.4.2 Calling a Database Procedure Statement

You can use the utilities API to execute a SQL call database procedure statement and return a list object for an out type parameter value list.

You can use the utilities.getSQLService().callProcedure("recid", "alias", "sql", "params") method to call the procedure and return a list object for out type, where:

  • recid is an optional Integer specifying the recorded ID.

  • alias is a String specifying the user-defined database alias specified for the database containing the procedure.

  • sql is a String specifying the SQL statement to be sent to the database, typically a static SQL to call database procedure statement.

  • params is an optional List<Object> object containing all the SQLService.parameter or SQLService.SQLParameterType-wrapped parameter values by index. The index starts with 1.

The following example shows the code used to define and connect to a database, call a database procedure, and disconnect from the database:

utilities.getSQLService().define("local_XE_DB",
   "oracle.jdbc.driver.OracleDriver",
   "jdbc:oracle:thin:@localhost:1521/XE", "system",
   ;deobfuscate("6GaD7eW3kGVe5TKHmuI/+w=="));

utilities.getSQLService().connect("local_XE_DB");

utilities.getSQLService().callProcedure(44, "local_XE_DB",
   "Begin\n  insertInfo2(014,'anna14',21,'F','ecnu14',
     'History','1288',to_date(?,'yyyy-mm-dd'));\nEnd;",
   utilities.parameters(
     SQLService.parameter("1989-02-18",
     SQLService.SQLParameterType.In)));

utilities.getSQLService().disconnect("local_XE_DB");      

2.11.5 Using the XPath Generator

The Utilities Module includes an XPath generator utility that you can use to generate an XPath Expression to a selected element from a valid XML file.

To use the XPath Generator:

  1. Create an XML file that contains the tags and values to use to generate the XPath expression. The following is an example of a simple XML file that can be used with the XPath Generator:

    <?xml version="1.0" encoding="utf-8"?>
    <Oceans>
       <ocean name="Artic"/>
       <ocean name="Atlantic"/>
       <ocean name="Indian"/>
       <ocean name="Pacific"/>
       <ocean name="Southern"/>
    </Oceans>
    
  2. Create and record a test script. The Tools menu appears on the OpenScript menu bar for functional and load test scripts.

  3. Select Generate XPaths from the Tools menu.

  4. Click Browse and select the XML file to load.

  5. Expand the XML tree under the Tags section of the XML file.

  6. Select the XML tag to use to generate the XPath. The generated XPath appears in the XPath Expression field in a form similar to /Oceans/ocean[1]/@name.

  7. Use the Ctrl+C and Ctrl+V keyboard combinations to copy and paste the generated XPath to a method in the Java Code tab of the script view.

    The XPath Expression can be used in the utilities findByXPath API method, as follows:

    utilities.loadXML("filePath").findByXPath(xpath, xml)
    

2.12 Debugging Scripts

You can use features of the Eclipse IDE to debug scripts. For debugging purposes, it is not always necessary to switch to the Debug Perspective to debug a script. You can add views to the Tester Perspective, such as Breakpoints, Debug, and Expressions views. In most cases, you do not need to use the Outline, Variables, and Tasks views. This section provides tips for basic script debugging techniques.

2.12.1 Adding Views to the Tester Perspective

In some cases, you may want to add additional views to the Tester Perspective for debugging purposes. You select the view to open using the shortcut keys to get to the Show View window.

To open the Show View window:

  1. Press and hold the Shift and Alt keys, then press the Q key (Shift+Alt+Q).

  2. Press the Q key again. The Show View window opens.

  3. If necessary, expand the Debug tree.

  4. Select the View(s) you want to open:

    • Press and hold the Shift key and click to select multiple contiguous view names.

    • Press and hold the Ctrl key and click to select multiple non-contiguous view names.

  5. Click OK.

The selected views open in the Tester Perspective.

Note:

If you are in the Developer Perspective, you can add a view by selecting Show View from the Window menu and then selecting Other.

2.12.2 Adding Breakpoints to a Script

You can add breakpoints to the Java Code to halt script execution at a specific line of code in the script.

To add a breakpoint to the script code:

  1. Create a script project.

  2. Record the script.

  3. In the Script view, click the Java Code tab.

  4. Double-click in the right-most column of the code view frame next to the code line where you want to add a breakpoint. You can also select Toggle Breakpoint from the right-click shortcut menu. The breakpoint indicator appears as a round dot in the frame. You can add as many breakpoints as needed.

  5. Play back the script.

    When you play back the script, code execution will stop at the breakpoint. The Confirm Perspective Switch message appears the when the code execution arrives at a breakpoint. Select the Remember my decision option if you do not want the message to appear again during future script playback.

  6. Click No to stay in the Tester perspective or Yes to switch to the Debug Perspective. You can use the following keyboard debug features to execute code while in debugging mode:

    • Single-step (F6) - executes the next line of code.

    • Step-into (F5) - opens the method/function class file.

      Note:

      Source code for the JRE or for the Eclipse IDE is not included with the product. When stepping into code, an editor may appear that does not contain source code. In this case, close the editor and resume script playback. You can use the Step-into feature to step into your own custom functions that you have added to a script.
    • Resume (F8) - resumes code execution to the script end or to the next breakpoint.

2.12.3 Adding a Java Exception Breakpoint

You can pause a script when any error occurs by adding a "Java Exception Breakpoint" to the Breakpoints list.

To add a Java Exception Breakpoint:

  1. Create a script project.

  2. Record the script.

  3. Open the Breakpoints view.

  4. Click the Add Java Exception Breakpoint icon on the Breakpoints View toolbar.

  5. Type "AbstractScriptException" and click OK to add this exception to the breakpoint list.

  6. Right-click on the breakpoint in the Breakpoints view and select Breakpoint Properties.

  7. Select the Suspend on Subclasses of this Exception option in the breakpoint properties and click OK.

During script playback, if an exception occurs, you can correct the problem and then continue script playback.

2.12.4 Pausing and Resuming Script Playback in Debug Mode

You can pause and resume script playback using the Tree view or the Debug view.

To pause and resume play back in the Tree view:

  1. Create a script project.

  2. Record the script.

  3. Play back the script.

  4. Click the Pause toolbar button to pause playback.

  5. Click the Resume toolbar button to resume playback of a paused script.

To pause and resume play back in Debug mode:

  1. Create a script project.

  2. Record the script.

  3. In the Script view, click the Java code tab.

  4. If necessary, add a Debug view to the Tester Perspective. If the Developer Perspective is open the Debug view should already be open.

  5. Play back the script.

  6. In the Debug view tree, select the Thread [Iterating Agent 1] thread and click the Pause toolbar button. The Thread [Iterating Agent 1] thread is the Virtual User's thread. You can ignore the others.

  7. In the Debug view tree, select script.run() and click the Resume toolbar button to resume playback.

    If you want to resume from a specific point in a script, comment out all lines before the current one, save the script, and then resume.

You can also execute portions of the script without having to comment out lines and restart the playback.

  1. Insert a breakpoint at the first line of the run() section.

  2. Playback the script. You can execute or inspect any line when playback halts a the breakpoint.

  3. Select the specific line(s) of code you want to playback, right-click and select Execute. You can modify the code and re-execute without having to save the script.

  4. Repeat the select code, right-click, Execute process until the script works the way you want it to work.

  5. Stop playback, or select the Resume button on the Debug view to replay from the breakpoint.

2.12.5 Inspecting and Changing Script Variable Values

You can inspect or watch script variable values to debug scripts. The script must be running or stopped at a breakpoint.

There is a difference between Java local variables and script variables. Java local variables are declared using standard Java syntax, such as String x or int i. Script variables are set using the OpenScript API methods, such as getVariables().set("someVariable", "123" or http.solve().

To inspect the value of a script variable:

  1. Create a script project.

  2. Record the script.

  3. Add a breakpoint to the script.

  4. Play back the script.

  5. At the breakpoint highlight the script code containing the variable or type the following code and highlight the code:

    getVariables().get("someVariable")
    
  6. Right-click and select Inspect or Watch.

    • Inspect opens a pane that shows the variable (Shift-Alt-I adds the variable to the Expressions view).

    • Watch copies the variable to the Expressions view.

  7. To change the value of a script variable, type the following code:

    getVariables().set("someVariable", "newValue")
    
  8. Highlight the code.

  9. Right-click and select Execute.

    Note:

    You can also test individual web actions by pausing the script, selecting the code for the action to test, then right-clicking and selecting Execute (or pressing Ctrl+U).

2.13 Enabling Debug Logging

OpenScript provides debug logging capability using Jakarta Log4j.

To enable debug logging:

  1. Close OpenScript.

  2. Open the file log4j.xml located in C:\OracleATS\OpenScript.

  3. Locate the following section at the end of the file:

  4. <!-- ======================= -->
      <!-- Setup the Root category -->
      <!-- ======================= -->
    
            <!-- For production  -->
      <root>
       <priority value="WARN"/>
       <appender-ref ref="AGENTFILE" />
      </root>
    
            <!-- For debugging
      <root>
       <priority value="DEBUG"/>
       <appender-ref ref="AGENTFILE" />
       <appender-ref ref="CONSOLE" />
      </root>
            -->
    
  5. Move the ending comment brackets from:

  6. <!-- For production  -->
      <root>
       <priority value="WARN"/>
       <appender-ref ref="AGENTFILE" />
      </root>
    
            <!-- For debugging
      <root>
       <priority value="DEBUG"/>
       <appender-ref ref="AGENTFILE" />
       <appender-ref ref="CONSOLE" />
      </root>
            -->
    

    to:

    <!-- For production
      <root>
       <priority value="WARN"/>
       <appender-ref ref="AGENTFILE" />
      </root>
            -->
    
            <!-- For debugging -->
      <root>
       <priority value="DEBUG"/>
       <appender-ref ref="AGENTFILE" />
       <appender-ref ref="CONSOLE" />
      </root>
    
  7. Save the file log4j.xml and restart OpenScript.

  8. Run scripts.

The debug messages are stored in the file OpenScript.log located in <installdir>\OpenScript.

To turn off debugging, move the ending comment braces back to the original locations.