← Back to ERP system builders
See how it helps
Stateful model-based tests
Generates sequences of actions against a simple reference model to find failures that isolated examples miss.
stateful-model-based-testing
Team members using this skill
When is it useful?
Use when correctness depends on the order of several operations.
What does it help you do?
- Defines model state and commands with valid preconditions.
- Compares actual results and invariants after each action.
- Reduces failing sequences to understandable minimal reproductions.
Try asking this
Model account creation, deposits and withdrawals; generate sequences that expose an incorrect balance after a rejected withdrawal. Generate deposit, successful withdrawal and rejected withdrawal sequences. Compare model and actual balance after every command, including commands that correctly fail.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Stateful & Model-Based Testing
Use this skill when bugs depend on the ordering, repetition, or interleaving of operations across stateful entities (credit wallets, subscriptions, orders, approvals, inventory reservations, or cache/DB synchronization).
State-Machine Command Architecture (Lamport & Hughes)
Model the system as an explicit state machine driven by generated sequences of Commands (fc.commands / fc.asyncModelRun in fast-check, RuleBasedStateMachine in Hypothesis):
- Shadow Model State ($M$):
- Maintain a minimal, transparent in-memory representation of the expected domain state (e.g.,
Map<AccountId, { balance: bigint, reserved: bigint, seenKeys: Set<string> }>). - Keep $M$ simple and free of production infrastructure concerns (no SQL, no caching, no framework middleware).
- Maintain a minimal, transparent in-memory representation of the expected domain state (e.g.,
- Command Catalog ($C_1, C_2, \dots, C_k$):
- Define a command for each domain action, including adversarial and duplicate actions:
- Normal lifecycle actions (
GrantCredit,Reserve,Capture,Release,Refund,Cancel). - Replay / duplicate actions (
ReplayLastRequestWithSameIdempotencyKey,DuplicateWebhookDelivery). - Invalid / out-of-order actions (
CaptureAlreadyReleasedReservation,OverRefund,ApproveOwnRequest).
- Normal lifecycle actions (
- Define a command for each domain action, including adversarial and duplicate actions:
- Command Contract (
check+run):- Precondition (
check(model)): Determines whether the command is applicable in the current model state. Include commands that specifically test invalid state transitions so rejection behavior is verified too. - Execution (
run(model, realSystem)):- Execute the operation against
realSystem. - If the operation is legal in
model, updatemodeland assert thatrealSystem's return value and observable state matchmodel. - If the operation is illegal in
model(e.g., insufficient funds or terminal state), assert thatrealSystemrejects it with the expected domain error and thatrealSystemstate remains completely unchanged.
- Execute the operation against
- Global Step Invariant: After every command in the sequence, assert global cross-entity invariants (e.g., ledger conservation, no negative available balances, cache matches DB).
- Precondition (
Designing Effective State-Space Exploration
- Pool-Based Entity References: Draw IDs, accounts, and reservations from bounded pools (
Bundlesin Hypothesis or shared model arrays infast-check) so generated commands repeatedly collide on the same entities instead of creating a fresh, isolated entity on every step. - Test State Re-Entry & Loops: Ensure command sequences can cycle through
reserve -> release -> reserve -> partial capture -> refundorsubscribe -> cancel -> reactivate -> upgradeto expose stale flags or leaked locks.
Checklist
- Does the shadow model track the essential business state clearly without copying production code?
- Do generated command sequences include replays, out-of-order calls, and rejected transitions alongside happy-path steps?
- Do commands draw from a shared pool of entities so multiple operations hit the same records?
- Are global state invariants verified after every individual command step, not only at the end of the run?
Included files 1
SKILL.md
