Skip to content

Given-When-Then

The Given-When-Then extension captures behavioral specifications about a single consistency unit. A feature document groups related scenarios under one fachliche Klammer; each scenario follows the canonical Given/When/Then pattern.

The format originated in BDD (Dan North) for general behavioral specs. The event-sourced flavor – Given <events>When <command|event|timer|query>Then <events|...> – traces back to Greg Young's aggregate-test pattern, and ESDM adopts it wholesale across all four kinds of consistency unit.

When You'd Reach for It

Use the GWT extension when you want to write down concrete behavior that domain experts can read and that the linter can check for structural soundness. Given a round in progress with three completed holes, when the player records the fourth hole, then a hole-completed Event is published.

The scenarios live alongside the model, in the same *.esdm.yaml files, version-controlled with the rest of the code. They double as living documentation and as input for tests – an implementation can run the scenarios as fixtures and verify that the system actually produces the events the spec calls for.

The Four Variants

A feature is about one consistency unit, and the unit's kind shapes the scenarios. The four variants are:

  • Aggregate featuresGiven <past events of this aggregate>When <command on this aggregate>Then <emitted events> or <rejection>. The classic Greg-Young aggregate test.
  • DCB features – same writer side as aggregate features, but Given carries full Event references because a DCB consults Events from many producers across its Bounded Context.
  • Process-manager featuresGiven carries the Event history that produced the current instance state, When is either an incoming Event or a timer firing, Then covers the broader reactive surface (emits, setTimers, cancelTimers, state, ended).
  • Read-model featuresGiven is the Event history, When is a Query plus parameters, Then is either the expected query result or the expected materialized Read Model.

The variant is determined by which discriminator field is present inside the feature's scopeaggregate, dynamicConsistencyBoundary, processManager, or readModel.

Where to Go Next

The Concepts page expands on the structure of a feature and a scenario. The Reference documents every field the schema accepts.