Skip to content

Getting Started

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

Getting Started

This guide takes you from zero to a passing BDD test against a Spring Boot application.

1. Add the dependency

See Installation for all options (BOM, Kotlin DSL, etc.).

Maven:

<dependency>
    <groupId>io.github.ragin-lundf</groupId>
    <artifactId>bdd-cucumber-gherkin-lib</artifactId>
    <version>${version.bdd-cucumber-gherkin-lib}</version>
    <scope>test</scope>
</dependency>

Gradle (Groovy):

dependencies {
    testImplementation "io.github.ragin-lundf:bdd-cucumber-gherkin-lib:${version.bdd-cucumber-gherkin-lib}"
}

Check the latest version on Maven Central.

2. Create a JUnit 5 runner

package com.example.tests

import io.cucumber.junit.platform.engine.Constants
import org.junit.platform.suite.api.*

@Suite
@IncludeEngines("cucumber")
@SelectClasspathResource("features")
@ConfigurationParameter(
    key = Constants.GLUE_PROPERTY_NAME,
    value = "com.ragin.bdd.cucumber.glue, " +
            "com.ragin.bdd.cucumber.hooks, " +
            "com.example.tests.hooks"
)
@ExcludeTags("ignore")
class CucumberRunner

The glue package com.ragin.bdd.cucumber.glue registers all library steps automatically. com.example.tests.hooks is where you put your own @ContextConfiguration (see step 3).

3. Configure the Spring test context

Create bdd-cucumber-gherkin-lib/src/test/resources/application.yml:

cucumberTest:
  authorization:
    bearerToken:
      default: "your-valid-test-token"
      noscope: "your-token-without-scopes"

For apps that have no database, also add:

cucumberTest:
  databaseless: true

See Configuration for all available options (proxy, SSL, predefined context values, etc.).

4. Write your first feature

Create bdd-cucumber-gherkin-lib/src/test/resources/features/hello/hello.feature:

Feature: Hello API

  Background:
    Given that all URLs are relative to "/api/v1"

  Scenario: Unauthenticated request returns 200
    When executing a GET call to "/hello"
    Then I ensure that the status code of the response is 200

  Scenario: Authenticated request returns the expected body
    When executing an authorized GET call to "/hello"
    Then I ensure that the response code is 200 and the body is equal to
      """
      {
        "message": "Hello, World!"
      }
      """

Run it with your normal test command (./gradlew test or mvn test).

5. Validate a JSON response from a file

For complex responses, keep expected JSON in a separate file so the feature stays readable.

bdd-cucumber-gherkin-lib/src/test/resources/features/hello/expected/response.json:

{
  "id": "${json-unit.matches:isValidUUID}",
  "message": "Hello, World!",
  "createdAt": "${json-unit.matches:isValidDate}"
}

Feature:

Feature: Hello API — file-based response validation

  Background:
    Given that all URLs are relative to "/api/v1"
    And that all file paths are relative to "features/hello"

  Scenario: Full response body matches expected structure
    When executing an authorized GET call to "/hello"
    Then I ensure that the response code is 200 and the body is equal to the file "expected/response.json"

The ${json-unit.matches:isValidUUID} and ${json-unit.matches:isValidDate} placeholders validate dynamic fields without requiring exact values. See JSON-Unit for all available matchers.

6. Typical full scenario: create then fetch

Feature: Resource lifecycle

  Background:
    Given that all URLs are relative to "/api/v1/resources"
    And that all file paths are relative to "features/resources"

  Scenario: Create a resource and fetch it by ID
    Given that the body of the request is
      """
      { "name": "My Resource" }
      """
    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 store the string of the field "id" in the context "RESOURCE_ID" for later usage

    Given that the request body in the scenario context map has been reset
    When executing an authorized GET call to "/${RESOURCE_ID}"
    Then I ensure that the response code is 200 and the body is equal to the file "expected/resource.json"

Next steps

Topic Page
Every available step All Steps — Quick Reference
Dynamic date generation Common — Dates
Poll until a condition is met When — Polling
Custom JSON matchers JSON-Unit
Proxy and SSL configuration Configuration
Database (Liquibase, SQL, CSV) Common — Database

Clone this wiki locally