YAML-Based Test Scenarios: One Test Class, Hundreds of Tests

───

The Problem

In complex business applications, you have many scenarios to test: happy paths, negative cases, edge cases, concurrency issues. Writing a separate Java test for each scenario means a lot of code duplication and tests that are hard to review by non-developers.

───

Architecture

YAML Scenario Files → ScenarioExecutor → Spring Boot Test with MockMvc

───

1. Scenario Model (Java Record)

The YAML structure maps to a Java record:

public record Scenario( String name, List steps ) { public record Step( String name, Api api ) {}

public record Api( String url, String requestMethod, List parameters, Map headers, int status, String body, String response ) {} }

───

2. Scenario Executor

The executor reads YAML and runs each step:

public boolean execute(Scenario scenario, String scenarioPath, ...) { for (var step : scenario.steps()) {

var response = getResponseBody(scenarioPath, step.api()); compareWithExpected(response, step.api());

} }

───

3. Test Class (One Class for All Scenarios)

class ScenarioTest {

@ParameterizedTest @MethodSource("getScenarioPathList") void allStepsTest(String stepPath) { var scenario = getScenario(stepPath); scenarioExecutor.execute( scenario, stepPath } }

───

4. YAML Scenario Example

story: name: create-order-test steps: - name: createOrder api: requestMethod: POST url: "/api/orders" body: /given/createOrderRequest.json response: /expected/createOrderResponse.json - name: getOrder api: requestMethod: GET url: "/api/orders/{orderId}" parameters: - orderId: "${order.id} response: /expected/getOrderResponse.json

───

5. Request/Response JSON Files

given/createOrderRequest.json:

{ "customerId": "customer-123", "items": [ { "productId": "product-1", "quantity": 2 }, { "productId": "product-2", "quantity": 1 } ], "totalAmount": 150.00 }

This means: you run tests, review the updated expected files, commit. No manual JSON editing.

───

6. Field Normalization

UUIDs, dates, and other dynamic fields are normalized before comparison so tests don't fail on timestamps or generated IDs.

───

8. Directory Structure

src/test/resources/scenario/ ├── create-order-test/

│ ├── scenario.yml │ ├── given/ │ │ └── createOrderRequest.json │ └── expected/ │ ├── createOrderResponse.json │ └── getOrderResponse.json ├── get-order-test/ │ └── scenario.yml └── ...

───

Result

Developers add a new scenario by creating a folder with YAML and JSON files. No Java code changes needed.

───

#testing #yaml #junit #springboot #integrationtesting #microservices