Contents


How to use test data in test and virtual services

Four ways to iterate over test data with Rational Integration Tester

Comments

The goal of using virtual services is to remove test dependencies and enable earlier testing. You can then build these techniques into a continuous delivery pipeline, thus ensuring each component is tested fully before delivery.

A virtual service is an emulation of an application or system. You can use this emulation in such a way that the system under test using the virtual service think that the life systems are still available. Implementing this technology enables the execution of tests earlier in the process and improves delivery velocity of higher-quality systems. IBM Rational® Integration Tester tests applications via their APIs and supports service virtualization by creating the virtual services.

This tutorial shows you four ways to use tests and virtual services to leverage test data with IBM Rational Integration Tester. Each example has distinct characteristics. Selecting the right implementation helps to reduce test and virtual service complexity, increase readability, and reduce maintenance.

This tutorial includes a sample project for download. The project is a web-based supermarket application that requests articles from a back-end system. The application requests a list of articles in one or more categories. A parameter accompanies each requested category and specifies the maximum number of articles to return. A price might accompany the article.

The sample project includes a virtual service, or stub, for a web service that selects a list of articles based on the requested category. The data is stored in a comma-separated text format (CSV) file. This tutorial explains how Rational Integration Tester uses this data file.

Best practices

When developing tests and stubs in software projects:

Accompany each stub with tests
Create one (or more) tests to validate the correct operation of a stub. Experience shows that the combination of testing and stubbing can deliver high-quality test artifacts. Make sure you name the tests and stubs clearly and logically. Don't make the testers and developers guess.

Include log actions in the test and stubs
When tests and stubs run in Rational Integration Tester, trace information appears in the Test Lab console. If the test or stub contains log actions, the output is displayed in the console; log actions can also write to a file (via the use of a variable called a tag). Log actions help enhance readability and guide the tester or developer in the flow of execution of a test or stub. You can also log actual values of tags during execution.

Same input results, same output
To reduce complexity, business logic might be distributed across multiple variants of a stub. When possible, keep the overlapping behavior the same. Consider the following growth of stub logic:

  • HardCoded: Return category Coffee with two items, all hard-coded.
  • SingleCategory_DataFile: Return requested category with all items from the data file.
  • MultiCategory_DataFile: Return multiple categories with a number of items from the data file.

When a single test requests the category Coffee, the virtual service should respond in the same way whether HardCoded, SingleCategory_DataFile, or MultiCategory_DataFile. It doesn't matter which stub is active; that test passes. This is an easy test to use to validate whether a stub is up and active.

Use more stringent tests to accompany the stubs when validating the specific logic. A request with multiple categories will pass on MultiCategory_DataFile but might fail on the other implementations of virtual service.

Implementations

This tutorial highlights four methods to iterate over and process test data. Selecting the right implementation helps to reduce test and virtual service complexity, increase readability, and reduce maintenance. The four methods are:

  1. Hard-coding data
    External test data
  2. Fetching test data
  3. Giving all category articles
    Maximizing returned list
    Business view and technical view
  4. Repeating on input, repeating on output
    Return articles with price unavailable

1 - Hard-coding data

The hard-coded implementation is simple, quick to create, and you can enhance it later.

A simple stub will suffice when you make assumptions on the request. For example, the client application requests only Coffee articles. The service provides only a fixed response.

To create the simple hard coded stub, you can opt to create a stub from the message exchange pattern (MEP). This will create a skeleton stub without any data. It's easy to add data to the request and response messages after the empty skeleton stub is created. This is called hard-coded because the data is embedded in the message structure and inside the project, instead of stored outside the project (for example, in a file on disk or in a database).

You can also create a test based on the message exchange pattern. It will automatically create an test with a basic request and reply messages. You'll only need to fill in the category Coffee; there's no need to bother with the reply message. When you start the stub and run the test, the test fails. You can quickly update the response with the received message.

At this point, the developer/tester can test the application using this stub. There is the limitation that the application under test can request only for Coffee.

External test data

External test data separates data from test/stub logic. This enables altering the behavior of tests/stubs by altering the test data only. It also provides options such as sharing the test data across multiple tests/stubs.

To support a more flexible response, create a table that groups the articles within categories and adds details such as inventory and price. The imported test data in the preview is shown in the figure below.

Imported test data (preview)
A table of articles is shown. The table consists of the columns                 Category, ArticleNumber, Article, Stock and Price. Articles are grouped by                 category. The category Coffee contains articles including whole beans and                 instant coffee.
A table of articles is shown. The table consists of the columns Category, ArticleNumber, Article, Stock and Price. Articles are grouped by category. The category Coffee contains articles including whole beans and instant coffee.

All provided stubs in the sample project share the same test data. Use the Copy column names to clipboard button to quickly create new tags (variables) in a new stub. Additionally, because the same names are used between columns and tags, a reference to the test data automatically maps the data from the columns to the tags – this is very handy when you have more than just the five columns shown in this sample.

2 - Fetching test data

Fetching a single row of data returns a single row of data and can be used within a loop to retrieve multiple rows of data.

It is easy to fetch the first test data row with the Fetch Test Data action. You can then use that data in the response message of the stub. The data is then mapped to tags (variables). Normally, this action is used in a loop to iterate over the test data.

The Fetch Test Data action mapping columns to tags
The figure shows the mapping of the tags and columns in a Fetch Test                 Data action.
The figure shows the mapping of the tags and columns in a Fetch Test Data action.

Because only one row of test data is read, the tags have simple values (not a list). Add the tags containing the data in the Send Reply action.

The Send Reply action showing the reply message with the tags
The Send Reply message of the shopping list containing a single                 article. The fields are populated with the tags. The tags contain the                 fetched data from the test data.
The Send Reply message of the shopping list containing a single article. The fields are populated with the tags. The tags contain the fetched data from the test data.

It's wise to use the context menu (accessible via right-click of the mouse) to place the tags into the fields. This eliminates errors in typing the text.

3 - Giving all category articles

The Lookup Test Data action is used to select multiple rows from test data in one step. This action maintains the simple structure in the test/stub.

The next implementation of the virtual service is to respond on the requesting category. The reply will give all articles of a category. This is implemented with the Lookup Test Data action. In the stub definition in the received request message, the category is stored in the tag %%filterCategory%%. Use this tag to filter the test data (Config tab > Lookup values).

Filtering data with a tag
In the Lookup Test Data action, in the Config tab, you can specify the                 filters. It will only retrieve those rows of data matching the filter                 criteria.
In the Lookup Test Data action, in the Config tab, you can specify the filters. It will only retrieve those rows of data matching the filter criteria.

The received data is a list of zero or more articles. Each column is stored into tags that can store multiple values (list tags).

Mapping selected rows mapped to appropriate tags
In the Lookup Test Data action, on the Store tab, data fields are                 mapped to appropriate tags, resulting in storing each list of values in                 each list tag.
In the Lookup Test Data action, on the Store tab, data fields are mapped to appropriate tags, resulting in storing each list of values in each list tag.

Rational Integration Tester automatically creates a response message based on the number of elements found in the list tags. You only need to specify that the article node in the reply message is repeating (using the contextual menu). This is visible by the red marker icon and green line in the figure below.

Marking the article node as repeating
The shopping list contains zero or more articles. This means that the                 article node needs the be specified as repeating. Depending on the                 provided data the structure of the resulting message will be tailored to                 the particular response that must be generated by the stub.
The shopping list contains zero or more articles. This means that the article node needs the be specified as repeating. Depending on the provided data the structure of the resulting message will be tailored to the particular response that must be generated by the stub.

The Lookup Test Data action can be powerful when the selection is done with one or more variables. The structure of the stub is also simple.

Maximizing the returned list

Use the Iterate Over Test Data action to fetch a row of data and process it directly.

In the previous example, all test data that satisfied the selection criteria was selected. That might be thousands of articles. But, what if you want only the first 10? To accomplish this, enhance the previous approach and remove any elements from the list above the number requested. That might result in fetching thousands of articles and deleting most of them.

There is another approach. Assume that only one category is requested. This value is stored in the appropriate tag (filterCategory) on the Input tab of the stub.

The logic of the stub is to iterate over test data with a filter applied. This fetches one row of test data matching the filter criteria and eliminates the need to apply separate logic for filtering.

Filtering in the Iterate Test Data action results
Adding a filter option to the Iterate Test Data will vastly reduce                 complexity. The selected row will meet the values assigned.
Adding a filter option to the Iterate Test Data will vastly reduce complexity. The selected row will meet the values assigned.

The Iterate Test Data action returns a single row of test data. It cannot return lists of values. The tags populated with the test data are simple values. If the collection lists (Java™ type ArrayList() ) is not yet holding maximum number of entries, you can add the values to the lists. The decision is shown in a Business View representation in the figure below.

The code to add the retrieved article to the collection lists is:

listArticle.add(tags["Article"]);
listPrice.add(tags["Price"]);
listStock.add(tags["Stock"]);
tags["listSize"]=listArticle.size();

The above code is represented in the business view of the stub as Function:Add to List, shown in the figure below.

Stub logic shown in the Business View
The image shows the Business View of the stub logic. With the Iterate                 Test Data action, a single row is fetched. If the size of the collection                 list is not at its maximum size, fetched data is added to the list.
The image shows the Business View of the stub logic. With the Iterate Test Data action, a single row is fetched. If the size of the collection list is not at its maximum size, fetched data is added to the list.

Business View and Technical View

The tests and stubs can be represented in two ways: the Business View and the Technical View (icon). Normally, the Technical View is used and provides details of the actions used. When large snippets of code are used to embed business logic, it can cloak the flow of the stub.

Showing the same stub in the technical view
technical view
technical view

To overcome this issue of getting an overview, you can switch to the Business View. This view provides the option to rename the actions in the test and stub. This option can dramatically improve the readability of the test and stub.

4 - Repeating on input, repeating on output

The previous example focused on the creation of the collection lists. Those lists were used in the reply message. This example lets you have multiple categories on the input as well.

On the input tab, the repetitive node must be marked as repeating. Within that node, the mapping of the field to the tag is defined. Enhance the mapping (Store tab) with the Append to list of values so that a single store results in a tag containing the list of categories to filter.

Use the Append to list of values to return lists of filterCategories
On the Input tab of the stub, open the Field Editor of the                 filterCategory node. On the Store tab, you can select Append to                     list of values. That results in a filterCategory tag, which                 will contain a list of values.
On the Input tab of the stub, open the Field Editor of the filterCategory node. On the Store tab, you can select Append to list of values. That results in a filterCategory tag, which will contain a list of values.

From the input of the stub, there is now a list of requested categories and a list with the appropriate maximum number of returned items. Iterate over this list using an Iterate While action. For each category, use the previously created Iterate Test Data to fetch rows of test data for that category. When the lists do not reach their maximum, the data is stored in the resulting lists.

Complex logic of fetching test data in the Business View
The Business View of the stub definition shows the logic of iterating                 on the filterCategory list. For each entry, the value is used for                 searching across the test data leveraging the Iterate Test Data                 action.
The Business View of the stub definition shows the logic of iterating on the filterCategory list. For each entry, the value is used for searching across the test data leveraging the Iterate Test Data action.

Returning articles with price unavailable

Each article might have a price in the test data file. If the price is available, it's processed the same as described above. An initial data file could assign all articles a price. But if the price is not available, the XML node should not appear in the reply message. Some additional logic is needed in the virtual service.

The above behavior can be implemented by setting those values to null as is done in the following ECMAScript logic. The removal of the XML node is automatic.

Note: Nothing changes in the Send Reply message. Depending on the provided data, it adapts automatically.

Adding a null value when price information is not available
By adding ECMAScript logic, you can hide the price node when no price                 is available. In the price lists, the appropriate value should be set to                 null so that the node will be removed from the reply message.
By adding ECMAScript logic, you can hide the price node when no price is available. In the price lists, the appropriate value should be set to null so that the node will be removed from the reply message.

Conclusion and recommendations

Rational Integration Tester gives the flexibility to create simple or complex virtual services. Both are of value in a test environment. Rational Integration Tester has several options for using test data. You can choose the best fit for your situation.

The unique combination of testing and stubbing in one tool helps deliver quality test assets.

When assumptions are made on the behavior of the virtual service, you can limit the complexity of the virtual service. This affects creation time and maintenance. When variants of the same virtual services are using the same (hard-coded) test data, the tests and stubs might be upward-compatible. The test for the simple stub can be reused for the complex stubs.


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational
ArticleID=1043025
ArticleTitle=How to use test data in test and virtual services
publish-date=03062017