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 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'
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 |
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'
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"
}
}
}
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
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
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
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
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 |
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'