Adding Parameter Options and Dynamic Responses to Transactions

Service Virtualization Transactions in the Asset Catalog support the use of parameter options to allow for more dynamic, realistic response data. You can reference values in a Transaction request to ensure that they are repeated appropriately in the response body. For example, if your Transaction is requesting a name, you can configure the response to return a random name.

There are two important components to a creating dynamic responses:

  • The parameters that control which data is returned, often based on request values
  • Helpers that control the format of the returned data

To add dynamic responses to a Transaction, use the following functions:

Import Transactions with Dynamic Responses

BlazeMeter supports preserving dynamic data from imported WireMock Transactions. WireMock uses Handlebar helper functions to dynamically generate responses, and BlazeMeter supports those functions. WireMock uses {{...}} notation, while BlazeMeter uses ${...} notation; however, BlazeMeter automatically adjusts the WireMock notation during import.

BlazeMeter also supports dynamic responses from imported RR pairs, as long as they use the supported ${...} notation.

For other source formats, like HAR, Swagger, and WSDL, import with dynamic responses data is not supported.

Add Dynamic Responses to a Transaction

When you add dynamic responses to an imported or manually created Transaction, you enrich the response data with information from the request. The referenced information can be either in a query parameter, the request header, a request cookie, or the request body.

Follow these steps:

  1. Open a Transaction in the Asset Catalog.
  2. Examine the Request data for potential values you want to parameterize and return in the response.
  3. Edit the Response Body to reference these values.
    All dynamic responses must be contained within ${...} notation. For more information, see Dynamic Response Examples.
    If you want to see a static response with a dollar curly bracket symbol (like ${XYZ}), use the backslash as an escape symbol in the response. For example, if you want to display the response ${xyz} at runtime, use the syntax \${xyz} in the Transaction's response body.
  4. To return values in the response based on request data, use one of the following helpers:

    • request.query.<parametername>
      Returns the value of the specified query parameter.
    • request.headers.<headername>
      Returns the value of the specified header. Within the response header, we are only evaluating the Value section. The Name in the header is not part of the dynamic response.
    • request.cookies.<cookieid>
      Returns the value of the specified cookie.
    • request.body
      Returns the full request body.

    Other helpers are available to configure formatting, conditional responses, numeric data, and more. For a list of all available Helpers, see Supported Helper Functions.

  5. Save the Transaction.

You can give certain parameters random values, while others can return an exact value from the request. For example, if a request is asking to create a user account, you can configure the response to return the requested data in the response.

Dynamic Response Examples

Here are a few simple examples of dynamic response usage:

Return Request Query Parameter Values

Consider a marketing system with lead information. You want to return records matching a specific type of lead.

This Transaction looks up leads with a status of HOT:

http://localhost:64755/leads?status=HOT

The following Transaction response configuration will return response information with the desired status:

Transaction response body example code.png

This configuration sets the status value to whatever you specify in the Transaction. Using this configuration, the original Transaction returns the following data:

response body example

Return Request Header Values

This example uses the Accept request header to send either a JSON or XML response based on the response time:

${#assign "mediaType"}${request.headers.Accept}${/assign}
${#eq mediaType 'application/json'}
{
  "users":[
    {
      "id":1,
      "name":"Mario Speedwagon",
      "status":"${request.query.status}"
    },
    {
      "id":2,
      "name":"Petey Cruiser",
      "status":"${request.query.status}"
    },
    {
      "id":3,
      "name":"Anna Sthesia",
      "status":"${request.query.status}"
    }
  ]
}
${/eq}
${#eq mediaType 'application/xml'}
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <users>
      <id>1</id>
      <name>Mario Speedwagon</name>
      <status>${request.query.status}</status>
   </users>
   <users>
      <id>2</id>
      <name>Petey Cruiser</name>
      <status>${request.query.status}</status>
   </users>
   <users>
      <id>3</id>
      <name>Anna Sthesia</name>
      <status>${request.query.status}</status>
   </users>
</root>
${/eq}

Consider the following example Transaction:

https://mockservicejan3130547pm839-8080-default.mock-new.blazemeter.com/leads?status=HOT

With the dynamic response data entered into the Transaction, it will return a value of HOT for the status and return the data in XML or JSON depending on the Accept header value in the request.

Here is the response to the example Transaction with an application/xml Accept header value:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <users>
      <id>1</id>
      <name>Mario Speedwagon</name>
      <status>HOT</status>
   </users>
   <users>
      <id>2</id>
      <name>Petey Cruiser</name>
      <status>HOT</status>
   </users>
   <users>
      <id>3</id>
      <name>Anna Sthesia</name>
      <status>HOT</status>
   </users>
</root>

Here is the response to the example Transaction with an application/json Accept header value:

{
  "users":[
    {
      "id":1,
      "name":"Mario Speedwagon",
      "status":"HOT"
    },
    {
      "id":2,
      "name":"Petey Cruiser",
      "status":"HOT"
    },
    {
      "id":3,
      "name":"Anna Sthesia",
      "status":"HOT"
    }
  ]
}

User Name Lookup - GET Request

This Transaction looks up a user name based on an ID number:

curl -X GET "https://contactapp.example.io/contact/1567" -H "accept: application/json"

While you may have recorded a few responses, you might also want a Transaction that returns realistic data when the other Transactions with recorded data are not matched.

The Request URL in BlazeMeter would look like this:

/contact/.*

To return a realistic ID and name value in the response, you would add the following to the Response Body:

magic string example code body

The request.path entry tells the response to use the first value in the request path as the value for the id parameter.

For the firstName parameter, the dynamic response creates a random alphabetic value of ten characters.

Account Creation - POST Request

This Transaction creates an account using a POST request with the required account data:

curl -X POST "https://contactapp.example.io/contact" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "firstName=John&lastName=Doe&phone=(999)-999-9999"

You want the response to return the requested data in the following format:

{
"id" : 3461,
"firstName" : "John" //The first letter should be capital
"lastName" : "DOE" //The whole string should be in upper case
"phone" : "(XXX)-XX-9999" // Only the last 4 digits needs to be visible
}

Here is how you would format the Transaction response body:

magic string example code with formatting syntax

The inputForm argument specifically references the parameters from the request. Each of the three parameters also includes a helper that puts the output in the desired format.

Supported Helper Functions

Helpers let you control the format, appearance, and other factors related to the output date of a dynamic response. BlazeMeter supports the following helpers:

Request Helpers

Name

Description

Example

request.query.<key>

Returns the value of the query parameter with the specified key

${request.query.status}

Returns the value of “status” query parameter.

Example:

http://localhost:80/test?status=InProgress

This request returns the following response:

InProgress

request.headers.<key>

Returns the value of the request header with the specified key.

${request.header.Accept}

Returns the value of the request header “Accept” .


Example:
http://localhost:80/test
This request with an Accept header of application/json returns the following response:
application/json

request.cookies.<key>

Returns the value of the cookie with the specified key.

${request.cookies.JSESSIONID}

Returns the value of the request header “JSESSIONID” .

Example:

http://localhost:80/test

This request with the JSESSIONID cookie value of 1A530637289A03B07199A44E8D531427 returns the following response:

1A530637289A03B07199A44E8D531427

request.body

Returns the value of the body.

s
${request.body}

Example:

Post Request http://localhost:80/test with a request body value of:
“PING”

This request returns the following response:
“PING”

String Helpers

Name

Description

Example

Example Response


capitalizeFirst
Capitalizes the first character of the value ${capitalizeFirst "hello world"} Hello world
center Centers the value in a field of a given width ${center "hello world" size=19 pad="-"} ----hello world----
cut Removes all values of an argument from the given string ${cut "hello world" "d"} hello worl
defaultlfEmpty If value evaluates to False, uses the given default. Otherwise, uses the value ${defaultlfEmpty "" "none"} none
join Joins an array, iterator, or an iterable with a string ${join "a" "b" "c" " // "} a // b // c
ljust Left aligns the value in a field of a given width ${ljust "Hello" size=10 pad=" "} “Hello “
rjust Right aligns the value in a field of a given width ${rjust "Hello" size=10 pad=" "} “ Hello”
substring Returns a new string that is a subsequence of this sequence. The subsequence starts with the char value at the specified index and ends with the char value at index end - 1 ${substring "Hello World" 0 5} Hello
lower Converts a string into all lowercase ${lower "HEllo"} hello
upper Converts a string into all uppercase ${upper "hellO"} HELLO
slugify Converts to lowercase, removes non-word characters (alphanumerics and underscores), and converts spaces to hyphens. Also strips leading and trailing whitespace ${slugify "Hello World"} hello-world
stringFormat Formats the variable according to the argument, a string formatting specifier ${stringFormat "Hello %s" "world"} Hello World
stripTags Strips all [X]HTML tags ${stripTags "<html><body><dummy>hello world</dummy></body></html>"} hello world
capitalize Capitalizes all the whitespace separated words in a String ${ capitalize "hello world"} Hello World
abbreviate Truncates a string if it is longer than the specified number of characters. Truncated strings end with a translatable ellipsis sequence ("..."). Argument: Number of characters to truncate to ${abbreviate "Hello World" 8} Hello...
wordWrap Wraps words at the specified line length. Argument: number of characters at which to wrap the text ${wordWrap "Lorem ipsum dolor sit amet, consectetur adipiscing elit." 14}

Lorem ipsum

dolor sit

amet,

consectetur

adipiscing

elit.

replace Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence ${ replace "Hello ..." "..." "world" } Hello world
yesno Maps values that resolve to true, false, and (optionally) null, to the strings "yes", "no", and "maybe", or given custom strings ${yesno true yes="Hello" no="world" maybe="none"} Hello
numberFormat

Format parameters is one of:

  • "integer": the integer number format

  • "percent": the percent number format

  • "currency"

${numberFormat .24 "percent"} 24%

Number Helpers

Name

Description

Example

Example Response

isEven

Returns a value only if the first argument is even. Otherwise, return null

${isEven 2 "Hello"}

Hello

isOdd

Returns a value only if the first argument is odd. Otherwise, return null

${isOdd 3 "World"}

World

stripes

Returns a different value if the passed argument is odd or even

${stripes 2 "Hello" "World"}

Hello

Conditional Helpers

Name

Description

Example

Example Response

eq

Tests if two elements are equals

${#eq request.path.0 "hello"}

"Hello is in the path"

${else}

"Hello is not in the path"

${/eq}

Returns “Hello is in the path” if the first part of the request’s path is equal to “Hello”; else returns "Hello is not in the path"

neq

Tests if two elements are NOT equals

${#neq request.path.0 "hello"}

"Hello is not in the path"

${else}

"Hello is in the path"

${/neq}

Returns “Hello is in the path” if the first part of the request’s path is equal to “Hello”; else returns "Hello is not in the path"

gt

Tests if the first argument is greater than the second one

${#gt request.path.0 "hi"}

"hello is lexicographically greater than hi"

${else}

"Hello is not lexicographically greater than hi"

${/gt}

Returns “hello is lexicographically greater than hi” if the first part of the request’s path is lexicographically greater than “hi”; else returns “Hello is not lexicographically greater than hi"

gte

Tests if the first argument is greater than or equal to the second one

${#gt request.path.0 "hi"}

"hello is lexicographically greater than hi"

${else}

"Hello is not lexicographically greater than hi"

${/gt}

Returns “hello is lexicographically greater than hi” if the first part of the request’s path is lexicographically greater than or equal to “hi”; else returns “Hello is not lexicographically greater than hi"

lt

Tests if the first argument is less than the second one

${#lt request.path.0 "hi"}

"hello is lexicographically lesser than hi"

${else}

"Hello is not lexicographically lesser than hi"

${/lt}

Returns “hello is lexicographically lesser than hi” if the first part of the request’s path is lexicographically lesser than “hi”; else returns “Hello is not lexicographically lesser than hi"

lte

Tests if the first argument is less than or equal to the second one

${#lte request.path.0 "hi"}

"hello is lexicographically lesser than hi"

${else}

"Hello is not lexicographically lesser than hi"

${/lte}

Returns “hello is lexicographically lesser than hi” if the first part of the request’s path is lexicographically lesser than or equal to “hi”; else returns “Hello is not lexicographically lesser than hi"

and

Truth of arguments is determined by isEmpty(), so this helper can be used with non-boolean values. Multiple values can also be specified

${#and true "NonEmptyString" 10 request.path.0}

Yes

${else}

No

${/and}

Returns “Yes”, as all the arguments evaluate to true

or

Truth of arguments is determined by isEmpty(), so this helper can be used with non-boolean values. Multiple values can also be specified

${#or false "NonEmptyString"}

Yes

${else}

No

${/or}

Returns “Yes”, as the second arguments evaluate to true

not

Truth of arguments is determined by isEmpty(), so this helper can be used with non-boolean values

${#not false}

Yes

${else}

No

${/not}

Yes

Assign Helpers

Name Description Example Example Response
assign Creates auxiliary variables

${#assign "title"}Hello World${/assign}

${title}

Hello World

WireMock Helpers

BlazeMeter supports WireMock helpers to support import from open source. By default, these helpers use {{...}} in WireMock. BlazeMeter automatically fixes imported Transactions to use the supported ${...} notation, but if you are manually adding these to a Transaction, use the proper BlazeMeter supported notation for them to work.

BlazeMeter supports the following WireMock helpers:

  • xPath
  • soapXPath
  • jsonPath
  • randomValue
  • hostname
  • date
  • now
  • parseDate
  • trim
  • base64
  • urlEncode
  • formData
  • regexExtract
  • size

For more information about these helpers, see wiremock.org/docs/response-templating.

Response Helper

Name Description Example Example Response
response.body

Returns the value that is specified in the Transaction→Response→Body field. Use this helper anywhere in the transactions, including HTTP calls and Wehbook calls.

Transaction → Response → Body contains name=$(config.myName}.
This body contains the value of a myName variable defined in the Configurations tab and assigns it to name at runtime.
Use this value in the body of the HTTP call or Webhook call as $(response.body}.
For example, myName=John.

During execution, name=$(config.myName} resolves to name=John.