Passing data between test steps


Overview

Most real world test automation scenarios require transferring data values between test steps (e.g. reading the order number generated by an API call and using it in the next step to validate the status of the order). OpenTest provides three techniques to store and retrieve this data:

  • The local data store - for data that is only accessed by the same test actor that generated it.

  • The shared data store - for data that is accessible across multiple test actors participating in a distributed test.

  • The session data store - for data that is accessible across multiple tests and test actors and lives through the complete test session.

Below is a graphical representation of the three data stores' lifetime:

OpenTest data stores lifetime
Figure 1. OpenTest data stores scope

Local data ($localData)

When a data value is only going to be needed in subsequent test actions running on the same test actor, the best technique to use is the local data store. This technique doesn’t incur any network traffic so it’s really fast. The local data store is a simple in-memory object that you can add properties to, so you can retrieve and use them later.

There are two ways to access the data values in the local data store:

  • The $localData object. This object can be used to read and write data properties to/from the local data store. Example:

    - script: |
        // Write the "username" property to local data
        $localData.username = "john_doe";
    
        // Read the username and log it
        $log("The username is " + $localData.username);
  • The $localData global test action argument. This argument can be specified when calling any regular test action or macro action. The value passed to this argument must be an object that contains one or more key-value pairs specifying a list of properties to be written into the local data store. Here’s an example of how we can write a property called "username" with the value that was outputted from a ReadElementText action:

    - description: |
        Read the username and write it to the "username" local
        data property
      action: org.getopentest.selenium.ReadElementText
      args:
          locator: {css: p.username}
          $localData:
            username: $output.text
    
    - description: Write the username into the "username" text box
      action: org.getopentest.selenium.SendKeys
      args:
        locator: {css: "input[name='username']"}
        text: $localData.username

Shared data ($sharedData)

When multiple test actors that participate in the same test need to share data with each other (and they typically do), you must use the shared data store technique instead. This works in a similar way with the local data store, but incurs a small performance penalty due to the additional network traffic it generates: the data is first sent to the sync service by the actor that is writing the data property; later on, it is requested from the sync service by the actor that reads it. Please make sure to only use the shared data store when you need to transfer data across actors, and use local data for all other needs. Just like with local data, there are two ways to access the shared data store:

  • The $sharedData object. This object can be used to read and write data properties to/from the shared data store. Example:

    ACTOR 1
    - script: |
        // Write the "username" property to shared data
        $sharedData.username  = "john_doe";
    ACTOR 2
    - script: |
        // Read the username from shared data and log it
        $log("The username is " + $sharedData.username);
  • The $sharedData global test action argument. This argument can be specified for any regular test action or macro action. The value passed to this argument must be an object that contains one or more key-value pairs specifying a list of properties to be written into the shared data store. In the example below, the test actor writes a property called "username" and populates it with the value of the text output generated by the ReadElementText action:

    ACTOR 1 (test fragment)
    - actor: ACTOR1
      segments:
        - segment: 1
          actions:
            - description: |
                Read the username and write it to the "username" shared
                data property
            action: org.getopentest.selenium.ReadElementText
            args:
                locator: {css: p.username}
                $sharedData:
                    username: $output.text

    The second test actor actor reads the shared username property in segment 2 of the test and uses it to specify the value of a test action argument:

    ACTOR 2 (test fragment)
    - actor: ACTOR2
      segments:
        - segment: 2
          actions:
            - description: Write the username into the "username" text box
              action: org.getopentest.selenium.SendKeys
              args:
                locator: {css: "input[name='username']"}
                text: $sharedData.username

Session data ($sessionData)

The session data store helps with sharing data between multiple tests in the same test session. Using the session data store creates dependencies between tests, which can be very hard to manage and control, so, as a best practice, avoid using it at all costs. Troubleshooting failed tests that use $sessionData is much more difficult, since you not only need to understand what happened in the test that failed, but also in all the other tests that executed before it in the same session. The syntax for working with the session data store is similar with the local and shared data stores, but using the $sessionData global action argument and the $sessionData object.