Introduction

This material is expected to provide a good review of the overall framework design and implementation for the Rational Robot SAFS Engine--also known as the "RRAFS Engine", or "DDE". The material is designed to help automators understand the engine infrastructure, and provides instruction for enhancing the engine with new functionality, keywords, or customizations.

Review Major Framework Elements

ELEMENTFILESDESCRIPTION
Cycle Driver CycleDriver.SBL The domain of the Test Designer. Executes a test that is, generally, a collection of test suites. CycleDriver invokes SuiteDriver for each suite in the test. At the Cycle level, suites are specified via a Test "T" record type.
Suite Driver SuiteDriver.SBL The domain of the Test Designer. Executes a suite that is, generally, a collection of action commands ordered to accomplish larger tasks. SuiteDriver invokes StepDriver for each action, or step, in the test. At the Suite level, these actions or tests are specified via a Test "T" record type.
Step Driver StepDriver.SBL The domain of the Test Automator. Executes the steps necessary to complete the specified action. This is typically an assortment of Driver Commands "C" and Component Function Test "T" actions.
Driver Commands DDDriverCommands.SBL Commands provided by the DDE to accomplish general purpose tasks generally not considered "tests". Things like setting global variables or execution parameters, launching applications, or waiting for other things to happen. At all test levels, Driver Commands are specified via the Command "C" record type.

There are actually several Driver Command libraries chained together at runtime. Among these are:

  • DDDriverCommands.SBL
  • DDDriverFlowCommands.SBL
  • DDDriverLogCommands.SBL
  • DDDriverCounterCommands.SBL
  • DDDriverDebugCommands.SBL
  • DDDriverDeprecatedCommands.SBL

There are also other engines like SAFS/DriverCommands that are independent of the RRAFS implementation. These can be launched and invoked by RRAFS to process additional Driver Commands that are not otherwise supported.

Component Functions ??????????Functions.SBL Libraries that implement the low-level actions for individual GUI components. Each library generally provides a set of actions for one specific type of component. CheckboxFunctions.SBL implements actions for Checkbox components. EditboxFunctions.SBL implements actions for Editbox components. And so on.

Low-level actions are things like "Click" the Button, "Set" the text value of an Editbox, or "Select" a RadioButton. Valid at the step level ONLY, component functions are called via the Test "T" record type.

There are also other engines like SAFS/RobotJ that are independent of the RRAFS implementation. These can be launched and invoked by RRAFS to process additional Component Functions that are not otherwise supported.

Action Map XSLComponentActions.MAP This is, essentially, a shorthand dictionary of all the component function actions implemented by the core RRAFS engine. The component function libraries use this dictionary to determine if they support an action that has been fed to them, or if they need to forward this action down the execution chain.

The engine will not act on any core component action command that does not exist in this Action Map.

Framework API\Utilities ??????????Utilities.SBL Support libraries implementing general purpose routines for facilitating test automation with Rational Robot. Utilities for working with files, strings, menus, or any other utility function we might have need for.


Back to Top

Source Structure

Robot's SQABasic does not support conditional compilation or inclusion based on something like #ifdef. Thus, it has an inherent problem with circular references or believing it has found duplicate definitions for the same item. The below 3-file library system minimizes the occurrence of duplicate definitions and\or circular references.

Source Structure for SQABasic Libraries
SomeUtilities.SBLlibrary sourcecode\logic; private stuff, etc.
SomeUtilities_X.SBHpublic Asset Header (constants, globals, types, etc.)
SomeUtilities.SBHpublic API Header for API declarations

Most support libraries and drivers use the 3-file system defined above. The named library will $Include its own Assets Header but will NOT include its API Header because that will cause duplicate definition compile errors. Other libraries wishing to take advantage of the named library will $Include both the Asset Header and the API Header--in that order.

Some libraries do not require the 3-file system. These libraries do not have public Assets or API to $Include or reference in other libraries. That may change over time. When a library exposes no public Assets, then it is completely self-contained in the SBL library file. The appropriate header file(s) get added later as needed to expose public assets or API declarations.

If you attempt to call a routine in a library that has not made that routine publicly available via an API Header, then you are asking for trouble. A routine that is not exposed in such a public header is allowed to change its signature. If it does, your private declarations for those routines will each have to be "fixed". So stick with the public API declarations provided by the public API headers. You have been warned.

Most all of the frameworks public Asset and API Headers can be included in your project with a single $Include statement:

This single header contains most key $Includes needed by developers working on scripts or libraries that are not part of the core framework.


Back to Top

DDE_RUNTIME vs. Project Locations


Back to Top

Review DDE Execution Flow


Back to Top

Custom vs. Core Actions


Back to Top

Adding Core Actions

As a reminder, and you will see this in the existing sourcecode, action commands and parameters are position dependent. The implementation expects to find parameters in specific fields. While many people may use DDVariable references to identify a parameter, the DDVariable itself is NOT used by the DDE in locating parameters. Parameters MUST reside in the specific field location identified for them.

Working example:

The two previous records are equivalent and will function. However, the following record is NOT equivalent and will probably generate an AppMap reference error:

Incorrect example:

The reason for the error is because SetContext is specifically looking for a Window reference in field #3, and a Child component reference in field #4. You cannot switch them around or assume they will be correctly interpreted by giving them some useful DDVariable reference.


Back to Top

Understanding Namespaces (also known as Scope)

The record types like "C" and "T" not only differentiate record format, routing, and intent; they also separate different namespaces. Driver Commands have a separate namespace from Component Functions.

The above is implemented and executed within the Driver Command libraries which have their own namespace. The call below happens to use the same action keyword, "SomeAction", but it is implemented in the libraries and namespace for Component Functions. It is a different action.

There are some not-so-obvious implications to this as we consider adding new Driver Commands and Component Functions.

Command processing will very often go through a long chain of attempts to locate a command implementation. Processing will continue until the first implementation of the command is found in the namespace, or until the entire chain has been searched and no implementation found.

For example, there are at least six libraries implementing Driver Commands (review). At runtime command processing will go through each of these libraries to locate the first implementation of a driver command and it will then execute that command. This obviously doesn't seem too problematic since all core driver commands must be unique. However, this is not so obvious when we are dealing with component function libraries and component actions.

Component Function actions like "Click" often get duplicated. There is a "Click" for a Pushbutton and there is a "Click" for a Window. (But not all components explicitly implement a "Click" action.) Each supported component type has its own Component Functions library where those actions are implemented. However, there is also a chain of libraries searched in the event the requested action is not implemented in the called library. This was demonstrated with the VerifyProperty action when we reviewed Generic Test Records.

So, while each Component Functions library loosely has its own namespace, this namespace is shared with a select few libraries in the chain of Generic command handling. This Generic handling chain is shown below:

  1. <componentType>Functions.SBL (ex: PushButtonFunctions.SBL)
  2. GenericObjectFunctions.SBL
  3. GenericMasterFunctions.SBL
  4. CustomTestCommands.SBL

This has the consequences shown in the following 2 lists:

Seeking a command in the chain that may be unimplemented:

  1. <componentType>Functions.SBL falls thru to
  2. GenericObjectFunctions.SBL falls thru to
  3. GenericMasterFunctions.SBL falls thru to
  4. CustomTestCommands.SBL error: unimplemented.

Implemented commands override implementations further down the chain:

  1. <componentType>Functions.SBL overrides
  2. GenericObjectFunctions.SBL overrides
  3. GenericMasterFunctions.SBL overrides
  4. CustomTestCommands.SBL may never get reached.

More information on avoiding namespace conflicts with truly custom actions is provided in the following section on Adding Custom Extensions.


Back to Top

Adding Custom Extensions

Custom extensions are those that are application or site-specific and cannot be distributed as part of the core framework. The DDE framework provides a mechanism by which you can implement custom features without modifying the core framework source. This enables you to continue to use and upgrade to future releases of the framework without losing your customizations and without going through a painful source merging process.


Back to Top

Framework Documentation Standards

There are two types of documentation that must be considered when reviewing or enhancing the framework libraries.

  1. The API Documentation provided by EACH library which represents how we call the routines provided by that library. This documentation is embedded in the library source.
  2. The separate XML Documentation for Keyword/Command syntax for the Core Driver Commands and Component Functions.

Originally, there was no separate XML Documentation Format. All API and Keyword documentation was embedded in the library API format. That did not allow for the automated publication of comprehensive reference material like the SAFS Reference. We have since separated these two different types of documentation content. Some older API-format documentation still contains what is now migrating into the XML format. Over time, this duplication should be eliminated.


Back to Top

Doc Publishing Tools

The framework primarily relies on structured documentation embedded within the sourcecode and in separate XML files. Tools exist to extract that documentation and publish it in HTML format for the web. Other tools process the separate XML keywords documentation to merge content into single-point references or data for use by other tools.

The framework developer needs to use these tools to (re)publish changes that occur to existing libraries or new documentation from new libraries.

XML processing uses the MSXML Parser and MSXSL.EXE from Microsoft. As of Oct, 2002 these have been bundled with the install of the RRAFS\DDE framework. They can also be downloaded and installed from Microsoft's XML Support Pages.