REST steps - veepee-oss/gingerspec GitHub Wiki


Check these examples:

For a complete list of steps definitions related to testing REST services, please check the corresponding class in the javadoc here


@Given("^I save element (in position '(.+?)' in )?'(.+?)' in environment variable '(.+?)'$")

Given a JSON, saves the element referenced by a JSONPATH in an environment variable

And I save element '$jsonpath' in environment variable 'myvariable'

If the JSONPATH returns an array of elements, you can specify the index of the element to save as follows

And I save element in position '0' in '$jsonpath.users' in environment variable 'user0'

This step is ussually used after getting the response from a remote REST service, for example:

Then the service response status must be '200'
And I save element '$.[0].userId' in environment variable 'USER_ID'

@Given("^I set headers:$")

Used to set headers of an HTTP request. This headers will be used for all the next HTTP requests within the same feature

Given I set headers:
 | x-user  | myuser  |
 | x-token | mytoken |

@Given("^I( securely)? send requests to '([^:]+?)(:.+?)?'$")

Is an inizialitation step, used to set the address of the remote endpoint, for example

Given I send requests to 'my-endpoint-address:port'

al further requests are based on that path, for example:

 When I send a 'GET' request to '/posts'

Will execute the request against my-endpoint-address:port/posts

This step will default to use http and port 80 (if port is not set). You can use the following variant to force https and port 443 (if port not set)

 Given I securely send requests to 'my-endpoint-address:port'

@Given("^I open a ssh connection to '(.+?)' with user '(.+?)'( and password '(.+?)')?( using pem file '(.+?)')?$")

Opens an ssh connection to the remote host. For rauthentication, the user can provide a password or a pem file in the following way:

Using password

Given I open a ssh connection to 'my-remote-server-address' with user 'root' and password '1234'

Using pem file

Given I open a ssh connection to 'my-remote-server-address' with user 'root' using pem file 'src/test/resources/credentials/key.pem'

If the connection was successful, you can later run commands in the remote server in the following way

Given I open a ssh connection to 'my-remote-server-address' with user 'root' using pem file 'src/test/resources/credentials/key.pem'
Then I run 'ls /tmp' in the ssh connection
When I run 'ls -la /tmp' in the ssh connection and save the value in environment variable 'VARIABLE'
Then '${VARIABLE}' contains 'total'

@When("^I send a '(.+?)' request to '(.+?)'( with user and password '(.+:.+?)')? based on '([^:]+?)'( as '(json|string)')? with:$")

Sends an HTTP requests to the endpoint specified. This step receives a file and a datatable to make changes on this file

For example. the file 'schemas/rest.json' contains a JSON with the structure of the body that needs to be sent in the POST request

{
 "user": "",
 "password": "",
}

During the request, the datatable is used to specify values of the different properties of the JSON object

When I send a 'POST' request to '/login' based on 'schemas/rest.json' as 'json' with:
 | $.user     | UPDATE | John |
 | $.password | UPDATE | 1234 |

So, the final body that is sent in the request would be this:

{
 "user": "John",
 "password": "1234",
}

Besides UPDATE, there are more actions that can be performed on the JSON object:


JSON STRING

Before Operation After

Before

Operation

After

ADD

{"key1":"val1", "key2":"val2"}

| key3 | ADD | val3 |

{"key1":"val1", "key2":"val2", "key3":"val3"}

"mystring"

| N/A | ADD | new |

"mystringnew"

DELETE

{"key1":"val1", "key2":"val2"}

| key1 | DELETE | N/A |

{"key2":"val2"}

"mystring"

| str | DELETE | N/A |

"mying"

UPDATE

{"key1":"val1", "key2":"val2"}

| key1 | UPDATE | newval1 |

{"key1":"newval1", "key2":"val2"}

"mystring"

| str | UPDATE | mod |

"mymoding"

APPEND

{"key1":"val1", "key2":"val2"}

| key1 | APPEND | new |

{"key1":"val1new", "key2":"val2"}

"mystring"

| N/A | APPEND | new |

"mystringnew"

PREPEND

{"key1":"val1", "key2":"val2"}

| key1 | PREPEND | new |

{"key1":"newval1", "key2":"val2"}

"mystring"

| N/A | PREPEND | new |

"newmystring"

REPLACE

{"key1":"val1", "key2":"val2"}

| key1 | REPLACE | al->alue 

{"key1":"value1", "key2":"val2"}

"mystring"

| str | REPLACE | mod |

"mymoding"

ADDTO

Used to insert the contents of one file into another, please check the step for creating files where

this action is explained in more detail

There is also a special action: "HEADERS". With "HEADERS", you can add headers to the request before sending (this headers will be used for all following requests within the same feature)

If you only want to alter the headers before the request is executed and no other modification, the step @Given("^I set headers:$") is prefered, since it does not require a file as parameter and is more readable and cleaner

When I send a 'POST' request to '/login' based on 'schemas/rest.json' as 'json' with:
 | $.user     | UPDATE | John                                                             |
 | $.password | UPDATE | 1234                                                             |
 | x-user     | HEADER | vente_privee_es                                                  |
 |  x-token   | HEADER | dd5e351b948372b2d807056ffbb53cef4a5eecce4dbfbb189844f5bca2c7c88f |

You can also provide the request with Basic Authentication by specifying login credentials in the step in the following way

When I send a 'POST' request to '/login' with user and password 'root:1234' based on 'schemas/rest.json' as 'json' with:
| $.user     | UPDATE | John |
| $.password | UPDATE | 1234 |

@When("^I send a '(.+?)' request to '(.+?)'( with user and password '(.+:.+?)')?( based on '([^:]+?)')?( as '(json|string)')?$")

Similar to the abode step, but in this case, no file or datatable is required

You can send a basic requets without file or datatable in the following way

When I send a 'GET' request to '/posts'

Or you can specify an static body (via a file) to be part of the request body

When I send a 'POST' request to '/login' based on 'schemas/rest.json' as 'json'

@Then("^the service response must contain the text '(.*?)'$")

Checks if the response returned by an HTTP requests contains an specifuc string

Example

Then the service response must contain the text 'Jenkins'

It can also be used after executing other validations (like the HTTP response status) for example

Given I securely send requests to 'jsonplaceholder.typicode.com:443'
When I send a 'GET' request to '/posts'
Then the service response status must be '200'
And the service response must contain the text 'Jenkins'

@Then("^the service response status must be '(.?)'( and its response length must be '(.?)' | and its response must contain the text '(.*?)' | and its response matches the schema in '(.+?)')?$")

Verifies at least two aspects of an HTTP response

As an example, lets test the response of "jsonplaceholder.typicode.com/todos/1" endpoint

Given I securely send requests to 'jsonplaceholder.typicode.com:443'
When I send a 'GET' request to '/todos/1'

The response should be this JSON object (lenght: 83 chars):

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

With this step, that JSON response can be validated in at least 3 ways:

1.-) Response status AND response lenght

Then the service response status must be '200' and its response length must be '83'

2.-) Response status AND response contains text

 Then the service response status must be '200' and its response must contain the text 'delectus'

3.-) Response status AND response json schema (in case of json response)

Then the service response status must be '200' and its response matches the schema in 'schemas/successful-response-schema.json'

Being 'schemas/successful-response-schema.json' a file containing a valid JSON schema:

{
  "$schema": "https://jsonplaceholder.typicode.com/todos/1",
  "title": "Successful response schema for /todos/1 endpoint",
  "description": "Schema to validate the json returned when a user make a requests to /todos/1 endpoint",
  "type": "object",
  "properties": {
    "userId":{
      "type": "number"
    },
    "id":{
      "type": "number"
    },
    "title":{
      "type": "string"
    },
    "completed":{
      "type": "boolean"
    }
  }
}

@Then("^'(.+?)' matches the following cases:$")

Evaluates the JSON object retorned by an HTTP request against different conditions outlined in a datatable

For example, Lets call the endpoint 'jsonplaceholder.typicode.com/todos/1' and save the response in the variable 'response'

Given I securely send requests to 'jsonplaceholder.typicode.com:443'
When I send a 'GET' request to '/todos/1'
And I save element '$' in environment variable 'response'

The JSON response has the following structure

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

The different parts can be evaluated using this step in the following way:

Then 'response' matches the following cases:
    | $.userId      | does not contain  | 2                  |
    | $.id          | equal             | 1                  |
    | $.title       | equal             | delectus aut autem |
    | $.completed   | not equal         | true               |

Avaliable operations:

  • does not contain
  • contains
  • not equal
  • size
  • equal

There is also an special operator ($.~), which is used to return the list of all first level json keys, for example, to evaluate that the JSON response contains the keys "userId" and "id"

Then 'response' matches the following cases:
    | $.~  | contains | userId   |
    | $.~  | contains | id       |

The $.~ operator only works with first level JSON keys. Trying to retrieve keys of nested objects won't work. Also, it won't work on arrays, only JSON objects ({}) is permitted

@Then("^'(?s)(.+?)' ((?!.*with).+?) '(.+?)'$")

Used to evaluate an expression against another. Typically used for comparing a value (string or numeric) saved on a variable against another

Example

Let's connect to a remote ssh server an execute a command. The result will be stored in the variable 'EVAR'

When I run 'echo test1' in the ssh connection and save the value in environment variable 'EVAR'

The variable EVAR can be evaluated using this spec in the following ways

 Then '${EVAR}' is 'test1'
 Then '${EVAR}' is different from 'test2'
 Then '${EVAR}' does not contain 'test2'

Available operations:

  • contains
  • is higher than
  • is different from
  • is is lower than
  • matches

@Then("^I clear headers from previous request$")

Clears any previously added headers in the same feature.

When adding headers to an HTTP request, either via

@Given("^I set headers:$")

or via (using datatable parameters)

@When("^I send a '(.+?)' request to '(.+?)'( with user and password '(.+:.+?)')? based on '([^:]+?)'( as '(json|string)')? with:$")

This headers are included in all following HTTP requests within the same feature. To avoid this, an clear any unwanted headers before sending a new request use this step in the following way:

Scenario: Correct credentials, successful login
  Given My app is running in 'mypage.com:80'
  Given I set headers:
    | x-user  | john.smith |
    | x-token | 1234567890 |
  When I send a 'GET' request to '/api/v1/user/1' as 'json'
  Then the service response status must be '200'
  And I clear headers from previous request
  .
  .
  .
  . (continue with other requests if necesary. neither x-user nor x-token will be included)

Notice how "My app is running ...." step is used here to initialize the remote endpoint. This step can be used in cucumber or rest scenarios, although, the step "@Given("^I( securely)? send requests to '([^:]+?)(:.+?)?'$")" is recommended

@Given("^I set url parameters:$")

Specify a custom map of url query parameters to be added to future requests using a datatable

Example
Scenario: URL parameters are added to the request
 Given I send requests to 'localhost:3000'
 Given I set url parameters:
   | userId | 3 |
 When I send a 'GET' request to '/posts'

This will create a GET request with userId as url query parameter ('/posts?userId=3')

Url query parameters are automatically added to any next request performed within the same scenario. Remember using the step '@Then("^I clear the url parameters from previous request$")' if you don't want this from happening

@Then("^I clear the url parameters from previous request$")

Clears the url query parameters that were configured in a previous step. Once the user uses the step to set url query parameters (Given I set url parameters), the parameters are automatically added to all future requests in the same scenario. This * step allows to delete this parameters from the system, so new requests are created without any url query parameters

Scenario: URL parameters are added to the request
 Given I send requests to 'localhost:3000'
 Given I set url parameters:
   | userId | 3 |
 When I send a 'GET' request to '/posts'
 Then the service response status must be '200'
 And I save element '$.[0]' in environment variable 'response'
 And 'response' matches the following cases:
   | $.userId | equal | 3 |
 Then I clear the url parameters from previous request
 Given I set url parameters:
   | userId | 4 |
 When I send a 'GET' request to '/posts'
 Then the service response status must be '200'
 And I save element '$.[0]' in environment variable 'response'
 And 'response' matches the following cases:
   | $.userId | equal | 4 |

@And("^I add the file in '(.+?)' to the request$")

Adds the specified file to the request as a form-params parameter (the request contentType must be changed to 'multipart/form-data')

Example

Given I send requests to 'myserviceurl.com'
    And I set url parameters:
      | campaignId | 123456 |
      | username   | admin  |
      | format     | EAN    |
    And I set headers:
      | Content-Type | multipart/form-data |
    And I add the file in 'schemas/myfiletosend.xls' to the request
    When I send a 'POST' request to '/uploadfile'
    Then the service response status must be '200'
⚠️ **GitHub.com Fallback** ⚠️