Scenarios as Tests
In EventFlow, every scenario with assertions is an executable test. Your documentation IS your test suite.
Scenarios ARE Tests
The test structure follows the familiar Given-When-Then pattern:
- Given: Initial state (
given:block) - When: Event trigger (
on :event) - Then: Assertions (
expect:block)
flow
machine: @shopping_cart
scenario: add item to empty cart
given:
@customer is logged in
cart is empty
$total: number is 0
on> :add_item from @customer
$items adds $item
$total increases by $item.price
expect:
= $items contains $item
expect:
= $items_count equals 1
= $total equals 1200Run with:
bash
eventflow test cart.flowAssertion Levels
Event-Level Assertions (Optional)
Verify after each event:
flow
on> :checkout from @customer
order moves to #awaiting_payment
expect:
= order is in #awaiting_paymentScenario-Level Assertions
Verify after all events complete:
flow
scenario: complete purchase
on> :checkout from @customer
order moves to #awaiting_payment
on :payment_success from @payment
order moves to #paid
on :stock_reserved from @inventory
order moves to #fulfilled
expect:
= order is in #fulfilled
= @customer received :order_confirmedRecommendation
- Use scenario-level
expect:for main test assertions - Use event-level
expect:for debugging or critical checkpoints
Test Granularity
| Level | What | EventFlow | Binding Code |
|---|---|---|---|
| Unit | Individual action/guard | N/A | Test each binding class |
| Integration | Event handler | Event-level expect | Test event flow |
| Feature | Full scenario | Scenario-level expect | Test complete feature |
Complete Test Example
flow
machine: @order
scenario: successful checkout
given:
@customer is logged in as "[email protected]"
@customer has verified payment method
cart contains:
| product | price |
| Laptop | 1200 |
| Mouse | 25 |
$total: number is 1225
on> :checkout from @customer
? cart is not empty
order moves to #awaiting_payment
emit :payment_request to @payment
expect:
= order is in #awaiting_payment
= :payment_request was emitted to @payment
on :payment_success from @payment
order moves to #paid
$paid_at becomes now
emit :order_confirmed to @customer
expect:
= order is in #paid
= $paid_at is not empty
expect:
= order is in #paid
= @customer received :order_confirmed
= $total equals 1225Assertion Patterns
State Assertions
flow
expect:
= order is in #paid
= order is not in #cancelled
= order has entered #processingContext Assertions
flow
expect:
= $total equals 1200
= $items_count equals 3
= $discount is greater than 0
= $customer_email is not emptyEvent Assertions
flow
expect:
= @customer received :order_confirmed
= :payment_request was emitted to @payment
= @warehouse received :prepare_shipmentCollection Assertions
flow
expect:
= $items contains "Laptop"
= $items is not empty
= $tags includes "urgent"Testing Multiple Scenarios
flow
machine: @order
scenario: successful checkout
given:
cart has items
payment method is valid
on> :checkout from @customer
order moves to #paid
expect:
= order is in #paid
scenario: checkout with empty cart
given:
cart is empty
on> :checkout from @customer
emit :empty_cart_error to @customer
expect:
= order is not in #paid
= @customer received :empty_cart_error
scenario: checkout with payment failure
given:
cart has items
payment will fail
on> :checkout from @customer
order moves to #awaiting_payment
on :payment_failed from @payment
order moves to #payment_failed
expect:
= order is in #payment_failedTest Runner Commands
bash
# Run all scenarios in a file
eventflow test order.flow
# Run specific scenario
eventflow test order.flow --scenario="successful checkout"
# Run all tests in directory
eventflow test ./flows/
# Run with verbose output
eventflow test order.flow --verbose
# Watch mode (re-run on file changes)
eventflow test order.flow --watchTesting Systems
Test entire multi-machine systems:
bash
# Test system with all machines
eventflow test system.flow
# Test specific flow across machines
eventflow test system.flow --scenario="complete purchase"Test Output
eventflow test order.flow
order.flow
✓ successful checkout (23ms)
✓ checkout with empty cart (12ms)
✓ checkout with payment failure (18ms)
3 passing (53ms)With failures:
eventflow test order.flow
order.flow
✓ successful checkout (23ms)
✗ checkout with empty cart (15ms)
Expected: order is in #error
Actual: order is in #awaiting_payment
1 passing, 1 failing (38ms)Best Practices
Test Happy Path and Edge Cases
flow
scenario: happy path - successful order
// Normal flow
scenario: edge case - empty cart
// Edge case
scenario: error case - payment failure
// Error handlingUse Descriptive Scenario Names
flow
// Good
scenario: customer can checkout with valid payment
scenario: checkout fails when cart is empty
scenario: order cancelled after 3 payment failures
// Avoid
scenario: test 1
scenario: checkout testKeep Scenarios Focused
flow
// Good - focused on one thing
scenario: add item updates total
given:
$total: number is 100
on> :add_item from @customer
$total increases by $item.price
expect:
= $total equals 150
// Avoid - testing too many things
scenario: full order flow test
// 50 lines of setup and assertions