Assertions
Assertions verify that your machine behaves correctly. They're marked with the = prefix and appear in expect: blocks.
Basic Syntax
flow
expect:
= order is in #paid
= $total equals 1200
= @customer received :confirmationState Assertions
Current State
flow
expect:
= order is in #paid
= order is in #awaiting_payment
= application is in #pendingNot in State
flow
expect:
= order is not in #cancelled
= order is not in #failedState History
flow
expect:
= order has entered #processing
= order has been in #pending
= order has never been in #cancelledContext Assertions
Equality
flow
expect:
= $total equals 1200
= $status equals "active"
= $is_premium equals trueComparisons
flow
expect:
= $total is greater than 100
= $total is less than 2000
= $total is at least 100
= $total is at most 500
= $discount is between 10 and 50Not Equal
flow
expect:
= $status is not "cancelled"
= $retry_count is not 0Empty/Not Empty
flow
expect:
= $customer_name is not empty
= $errors is empty
= $items is not emptyCollection Assertions
Contains
flow
expect:
= $items contains "Laptop"
= $tags contains "urgent"
= $roles contains "admin"Count
flow
expect:
= $items has 3 items
= $items_count equals 3
= $errors has 0 itemsEmpty/Not Empty
flow
expect:
= $items is not empty
= $errors is empty
= $cart has itemsEvent Assertions
Event Received
flow
expect:
= @customer received :order_confirmed
= @payment received :refund_request
= @warehouse received :ship_orderEvent Emitted
flow
expect:
= :payment_request was emitted to @payment
= :notification was sent to @customerEvent Not Received
flow
expect:
= @customer did not receive :error
= :refund was not emittedEvent with Data
flow
expect:
= @payment received :payment_request with $total
= :order_confirmed was emitted with order_id: $order_idBoolean Assertions
flow
expect:
= $is_active is true
= $is_cancelled is false
= $has_discount is trueTimestamp Assertions
flow
expect:
= $created_at is not empty
= $updated_at is after $created_at
= $completed_at is todayNegation
Use not or is not for negative assertions:
flow
expect:
= order is not in #cancelled
= $total is not 0
= $items does not contain "Expired Item"
= @customer did not receive :errorMultiple Assertions
All assertions in an expect: block must pass:
flow
expect:
= order is in #paid // AND
= $total equals 1200 // AND
= @customer received :confirmation // AND
= $items has 3 items // All must passEvent-Level vs Scenario-Level
Event-Level (after specific event)
flow
on> :checkout from @customer
order moves to #awaiting_payment
expect:
= order is in #awaiting_payment // Checked after :checkoutScenario-Level (after all events)
flow
scenario: complete purchase
on> :checkout from @customer
...
on :payment_success from @payment
...
expect:
= order is in #paid // Checked after all eventsAssertion Patterns
Verify State Transition
flow
scenario: order payment
given:
order is in #pending
on> :payment_received from @payment
order moves to #paid
expect:
= order is not in #pending
= order is in #paidVerify Context Update
flow
scenario: apply discount
given:
$total: number is 100
$discount: number is 0
on> :apply_coupon from @customer
$discount becomes 10
$total decreases by $discount
expect:
= $discount equals 10
= $total equals 90Verify Event Communication
flow
scenario: order triggers payment
on> :checkout from @customer
emit :payment_request to @payment
expect:
= :payment_request was emitted to @payment
= @payment received :payment_requestVerify Error Handling
flow
scenario: handle invalid cart
given:
cart is empty
on> :checkout from @customer
? cart is empty
emit :checkout_error to @customer
expect:
= order is not in #processing
= @customer received :checkout_errorCustom Assertions
For complex assertions, use natural language that maps to bindings:
flow
expect:
= payment was processed successfully
= inventory was updated correctly
= email was sent to customerThese map to custom assertion classes in your binding code.
Assertion Debugging
When assertions fail, you get detailed output:
✗ order is in #paid
Expected: #paid
Actual: #awaiting_payment
Event trace:
1. :checkout → #awaiting_payment
2. :payment_failed → #awaiting_payment (no transition)Best Practices
Be Specific
flow
// Good - specific
expect:
= $total equals 1200
= order is in #paid
// Avoid - vague
expect:
= order is valid
= everything workedTest What Matters
flow
// Good - testing the outcome
expect:
= order is in #paid
= @customer received :confirmation
// Avoid - testing implementation details
expect:
= internal_counter equals 5
= temp_flag is trueCover Edge Cases
flow
scenario: empty cart checkout
given:
cart is empty
on> :checkout from @customer
...
expect:
= order is not in #paid
= @customer received :empty_cart_errorGroup Related Assertions
flow
expect:
// State assertions
= order is in #completed
// Context assertions
= $total equals 1200
= $items_count equals 3
// Event assertions
= @customer received :confirmation
= @warehouse received :ship_order