Skip to content

Steps Then Validation

Jörg Flade edited this page Jun 24, 2026 · 3 revisions

Then — Validation


Validate HTTP Response Code

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 401

Validate Response Body with JSON File

Then 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.


Validate Response Body with Inline JSON

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

Validate Response Code and Body Together

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

Validate Only Specific Fields

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.

Single field

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

Multiple fields

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                         |

Special values: not-exist and not-equal

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_not requires 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.


Validate Response HTTP Header

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


Examples

Body validation examples: bdd-cucumber-gherkin-lib/src/test/resources/features/body_validation/

Clone this wiki locally