Skip to main content

Given-When-Then is not just syntax. It's a mindset.

· 2 min read
Daniel Maß
Maintainer of Xcepto

For years, system tests have been written with Arrange–Act–Assert.

That works — until asynchronous behavior enters the picture.

AAA implicitly assumes synchronicity: Arrange, then Act, then Assert — as if the system has already settled. But distributed systems don't behave like that.

  • An API call may publish an event
  • A queue consumer may process it later
  • A workflow may eventually converge

Timing becomes unpredictable.

The common workaround? Sleep(5000), retries, polling loops. Fragile tests built on timing assumptions.

Waiting for causality

The real problem is this: we wait for time instead of waiting for causality.

In asynchronous systems, timing should be causal rather than actual.

Instead of:

"Wait 5 seconds, then assert"

you say:

"Wait until this condition becomes true, then continue"

That is the real power behind Given–When–Then.

  1. Given a scenario
  2. When a condition becomes true
  3. Then validate the resulting system state

And once you think about testing causally, an interesting property emerges: you can chain multiple When → Then transitions together. Each validated state becomes the next Given.

The Xcepto execution model

This is exactly the model behind Xcepto. Tests are compiled into condition-driven state machines where transitions happen because conditions are satisfied — not because enough time passed.

  • No manual sleeps
  • No retry loops
  • No pretending distributed systems are synchronous

Originally published on themassiveone.net.