Skip to main content

Logical Test Components

Logical components are a type of component that you can add to a test using the Compose tab (aka Composer). To learn how to access components, see Adding Components to Tests.

Logical Components

What You'll Need#

Logical Components#

Each#

Allows you to iterate over a collection of elements and execute the piece of code for each element.

Parameters
Fields
Expression

| REQUIRED | EXPRESSION |

The path of the collection you want to iterate on.


Examples1each.jpg

The for each 'legs' collection checks if vector item is an integer value.

If a collection is nested in another one, you need to refer to them as _1, _2, and so on.

nestedEach.jpg

The for each payload.content.flights collection checks if price.amount is an integer. Then, the for each legs array, a nested collection within the flights collection, checks if vector item is an integer value.

If#

Allows you to run a specific piece of code only if a specific condition is met.

Parameters
Fields
Expression

| REQUIRED | EXPRESSION |

The condition that evaluates whether or not the code must be executed.


Examplesif.jpg

If payload.success is equal to true then the code within the element is executed, otherwise is skipped.

ifexists.jpg

If _1.intermediate exists then the code within the element is executed, otherwise is skipped. This is useful when the element is not always present.

While#

Allows you to run a block of assertions as long as a condition is valid.

Parameters
Fields
Expression

| REQUIRED | EXPRESSION |

The condition that has to be met for the assertions block to be executed.


Examples
while.jpg

Using Expressions#

Expressions — required for all logical components — are fields that reference an item in the test scope. The item can be a variable or an inner value in a data structure, such as a JSON. Most expressions will start with the name of the variable the data is stored in.

When working with structured data, expression is the path for reaching out a specific element. Most of the time, it's just object dot notation. In this example, we will assume the data has been assigned to a variable named payload:

"data":{  "created_time": "1453198835",  "images": {    "thumbnail": {      "width": 150,      "url": "https://domain.com/photos/9451802655724661601789699.jpg",      "height": 150      }   },  "Total-items": 1}

If you want to reach the value of the created\_time attribute:

payload.data.created_time

If you want to check the width of the images:

payload.data.images.thumbnail.width

Special Characters#

The "Total-items" element is a bit tricky, because the minus sign ( - ) would be misunderstood and treated as a subtraction operation. For this reason, the dot notation would require square brackets:

data['Total-Items']

XML#

The above statements are valid for both JSON and XML. When you have to reference XML attributes, the dot notation is valid, but the attribute has to be written between the square brackets and preceded by the @.

Example:

<HotelList size="2">    <HotelSummary order="0">        <hotelId>20160502</hotelId>        <name>Hotel One</name>

If we want to check the size attribute, you have to write:

payload['@size']
note

In XML, the root element is the variable itself, so you won't need to reference it explicitly.

Functions#

Expressions can also contain directives to transform the data you are willing to evaluate. For instance:

<HotelList size="2">    <HotelSummary order="0">        <hotelId>20160502</hotelId>        <name>Hotel One</name>
payload.HotelSummary.size()

Will count the number of instances of HotelSummary.

Expressions "Everywhere"#

Expressions are automatically evaluated in the expression fields, but can also be introduced in other fields, such as "value", with a specific notation.

In this example, we compare the actual size of the collection with the "size attribute", by enclosing the expression within ${ .. }. The "type" attribute ensures the comparison will happen with a numeric comparator, rather than string.
assertEquals

Expression Language Extensions#

Our API Testing expression language is mostly used to identify a path in a payload or reference a variable. But there's more to it. A number of extensions are available to generate calculated data, determine the quality of a value and so on.

These extensions can be used in any field that can be evaluated, which means in all expression fields, and all the fields where the value is wrapped in the ${...} brackets.

WSUtil#

This is the main extension. It supports many useful functions.

  • exists(object : Object) : Boolean : an XML and JSON existence state is different by definition. Use this in an "if statement" if a test should work both with JSON and XML

  • contains(substring : String, object : Object) : Boolean : returns true whether the string version of "object" contains the "substring" sub-string.

    WSUtil.contains('banana', payload.fruit.name)
  • isInteger(string: String) , isFloat(string: String), isUrl(string: String), isEmail(string: String), isPhoneNumber(string: String), isBoolean(string: String), isArray(object: Object), isMap(object: Object), isCreditCard(string: String) : Boolean : evaluate the nature of a data item

anyArrray.pick(n)#

Given any array, you can ask the system to create a random subset of it. One typical usage is when an iterator would turn out to be huge, and you prefer to cherry-pick a few items. The code will return an array of five random elements off the artists array.

payload.artists.pick(5)

A hands on example:

<each expression="payload.artists.pick(5)"> <assert-exists expression="_1.href" /> <assert-exists expression="_1.id" /> ... </each>

anyArrray.pick()#

Similar to the pick(n), this method will pick one random item off an array, and return it.

N#

Utility functions for numbers.

  • random(min: Int, max: Int) : Int : generates a random integer number between min and max.

    N.random(10,30)
  • random(min: Int, max: Int, quantity: Int) : List : generates a list of random numbers

    N.random(10,30,5)

D#

Plays with dates.

  • nowMillis() : Int : returns the current Unix epoch in milliseconds.
  • plusDays(millis: Int, days: Int): Int : returns the provided milliseconds, plus the provided number of days
  • plusHours(millis: Int, hours: Int): Int : returns the provided milliseconds, plus the provided number of hours
  • minusDays(millis: Int, days: Int) : Int : returns the provided milliseconds, minus the provided number of days
  • minusHours(millis: Int, hours: Int): Int : returns the provided milliseconds, minus the provided number of hours
  • format(millis: Int, format: String) : String : creates a timestamp with the given format, using the current timezone
  • format(millis: Int, format: String, timezone: String) : String : creates a timestamp with the given format, based on the provided timezone id
  • format(millis: Int, format: String, offset: Int) : String : creates a timestamp with the given format, based on the provided timezone offset
  • parse(timestamp: String) : Int : tries to parse the provided timestamp and convert it in milliseconds. It will use current timezone if not provided

Here's the conversion map for formats:

SymbolMeaningPresentationExamples
Ccentury of era (>=0)number20
Yyear of era (>=0)year1996
xweekyearyear1996
wweek of weekyearnumber27
eday of weeknumber2
Eday of weektextTuesday; Tue
yyearyear1996
Dday of yearnumber189
Mmonth of yearmonthJuly; Jul; 07
dday of monthnumber10
ahalfday of daytextPM
Khour of halfday (0~11)number0
hclockhour of halfday (1~12)number12
Hhour of day (0~23)number0
kclockhour of day (1~24)number24
mminute of hournumber30
ssecond of minutenumber55
Sfraction of secondmillis978
Ztime zone offset/idzone-0800; -08:00; America/Los_Angeles

WSCrypto#

Encryption utilities:

  • md5(input : String) : String : returns the md5 hash of the input string.
  • hash(input : String) : String : returns the SHA-1 hash of the input string, hex encoded.
  • base64(action: String, input: String) : decodes from or encodes into a base64 string. Action can either be 'encode' or 'decode'.
    WSCrypto.base64('encode','whatever')
  • sha256(input : String) : String : creates an hash of input using the SHA-256 algorithm.
  • sha256(input : String, secret : String) : String : encrypts input with secret using the HMAC-SHA256 algorithm.
  • hmacSha1(input : String, secret : String) : String : encrypts input with secret using the HMAC-SHA1 algorithm.