-
Notifications
You must be signed in to change notification settings - Fork 2
Steps Then Validation
- Validate HTTP Response Code
- Validate Response Body with JSON File
- Validate Response Body with Inline JSON
- Validate Response Code and Body Together
- Validate Only Specific Fields
- Validate Response HTTP Header
- Examples
Then I ensure that the status code of the response is {int}Asserts the response HTTP status code.
Scenario: Fetch returns 200
When executing an authorized GET call to "/api/v1/users/123"
Then I ensure that the status code of the response is 200
Scenario: Create returns 201
Given that the body of the request is
"""
{ "name": "Alice" }
"""
When executing an authorized POST call to "/api/v1/users" with previously given body
Then I ensure that the status code of the response is 201
Scenario: Missing resource returns 404
When executing an authorized GET call to "/api/v1/users/does-not-exist"
Then I ensure that the status code of the response is 404
Scenario: Unauthenticated returns 401
When executing a GET call to "/api/v1/protected"
Then I ensure that the status code of the response is 401Then I ensure that the body of the response is equal to the file {string}Compares the full response body against the contents of the given JSON file. The file path respects the base file path set with Set Base Path for Files.
JSON files can use JSON-Unit placeholders to validate dynamic fields:
features/users/expected/created_user.json:
{
"id": "${json-unit.matches:isValidUUID}",
"firstName": "Alice",
"lastName": "Smith",
"createdAt": "${json-unit.matches:isValidDate}"
}Feature:
Feature: Users API
Background:
Given that all file paths are relative to "features/users"
And that all URLs are relative to "/api/v1/users"
Scenario: Create a user and validate the full response
Given that the file "request/create_user.json" is used as the body
When executing an authorized POST call to "" with previously given body
Then I ensure that the status code of the response is 201
And I ensure that the body of the response is equal to the file "expected/created_user.json"See JSON-Unit for all available matchers including UUID, date, IBAN, and custom matchers.
Then I ensure that the body of the response is equal to
"""
{
"field": "value"
}
"""Compares the full response body against the inline JSON doc-string. JSON-Unit matchers work here too.
Scenario: Validate a short response inline
When executing an authorized GET call to "/api/v1/status"
Then I ensure that the status code of the response is 200
And I ensure that the body of the response is equal to
"""
{
"status": "UP",
"version": "${json-unit.ignore}"
}
"""
Scenario: Validate a created resource inline
Given that the body of the request is
"""
{ "name": "Test Item" }
"""
When executing an authorized POST call to "/api/v1/items" with previously given body
Then I ensure that the body of the response is equal to
"""
{
"id": "${json-unit.matches:isValidUUID}",
"name": "Test Item"
}
"""Use these steps when you always want to assert both the status code and the body in one line.
With inline JSON:
Then I ensure that the response code is {int} and the body is equal to
"""
{
"field": "value"
}
"""With a file:
Then I ensure that the response code is {int} and the body is equal to the file {string}Scenario: Create and validate in one step
Given that all file paths are relative to "features/users"
And that the file "request/create_user.json" is used as the body
When executing an authorized POST call to "/api/v1/users" with previously given body
Then I ensure that the response code is 201 and the body is equal to the file "expected/created_user.json"
Scenario: Inline validation
When executing an authorized GET call to "/api/v1/health"
Then I ensure that the response code is 200 and the body is equal to
"""
{ "status": "UP" }
"""These steps compare individual fields of the response body rather than the entire body. Use them when you only care about a subset of the response or want to check a single field.
The field argument supports:
- Simple field name:
"status" - Nested path (dot notation):
"address.city"or"$.address.city" - Array element:
"items[0].name"or"$.items[0].name"
The expected value is first resolved from ScenarioContext — if a matching key exists, the stored value is substituted.
Then I ensure that the body of the response contains a field {string} with the value {string}Scenario: Spot-check individual response fields
When executing an authorized GET call to "/api/v1/users/123"
Then I ensure that the status code of the response is 200
And I ensure that the body of the response contains a field "firstName" with the value "Alice"
And I ensure that the body of the response contains a field "address.city" with the value "Berlin"
And I ensure that the body of the response contains a field "items[0].name" with the value "First Item"
And I ensure that the body of the response contains a field "id" with the value "${json-unit.matches:isValidUUID}"Then I ensure that the body of the response contains the following fields and values
| fieldName | expectedValue |
| status | ACTIVE |
| count | 3 |
| items[0].name | First Item |
| id | ${json-unit.matches:isValidUUID} |
| object.lastname | Doe |The first column is the field path, the second is the expected value. No header row is needed.
Scenario: Validate multiple fields
When executing an authorized GET call to "/api/v1/users/123"
Then I ensure that the body of the response contains the following fields and values
| firstName | Alice |
| lastName | Smith |
| id | ${json-unit.matches:isValidUUID} |
| address.city | Berlin |
| items[0].name | Notebook || Reserved value | Meaning |
|---|---|
@bdd_lib_not_exist |
The field must be absent from the response |
@bdd_lib_not <value> |
The field must not equal <value>
|
Scenario: Deleted user has no token and non-zero ID
When executing an authorized DELETE call to "/api/v1/users/123"
Then I ensure that the status code of the response is 200
And I ensure that the body of the response contains a field "token" with the value "@bdd_lib_not_exist"
And I ensure that the body of the response contains a field "$.count" with the value "@bdd_lib_not 0"Note:
@bdd_lib_notrequires a space between the keyword and the value:"@bdd_lib_not someValue"— not"@bdd_lib_notsomeValue". Using!as a negation prefix is not supported, as!can be a valid field value.
JSON-Unit matchers: Only unparameterized matchers (e.g.
${json-unit.matches:isValidUUID}) can be used with single-field validation. Parameterized matchers require full-body comparison. See JSON-Unit.
Then I ensure, that the header {string} is equal to {string}Checks that an HTTP response header contains the expected value. Headers are treated as arrays — if you need to check multiple values, separate them with commas.
Scenario: Verify a custom response header is present
When executing an authorized GET call to "/api/v1/resource"
Then I ensure that the status code of the response is 200
And I ensure, that the header "X-TEST-HEADER" is equal to "present"
Scenario: Verify security headers are set correctly
When executing an authorized GET call to "/api/v1/secured-resource"
Then I ensure that the status code of the response is 200
And I ensure, that the header "X-Content-Type-Options" is equal to "nosniff"
And I ensure, that the header "Cache-Control" is equal to "no-store, no-cache"See bdd-cucumber-gherkin-lib/src/test/resources/features/header/header.feature
Body validation examples: bdd-cucumber-gherkin-lib/src/test/resources/features/body_validation/