How to

Testing contracts

A contract is only as good as its refusals. Test both sides of every rule.

In the Workbench

For each action, write at least:

  1. One accepted step — the normal case.
  2. One refused step per validation line — break exactly one rule each time, and check the reason names it.
  3. One step from the wrong signer — "actor": "someone_else".
  4. One query — that it returns the rows you expect, and none you don't.

A good trial reads like a story:

{
  "steps": [
    {"action": "Lend",   "subject": "drill", "args": {"ref": "drill", "owner": "$julien", "item": "Cordless drill", "borrower": "Ana"}},
    {"action": "Lend",   "subject": "drill", "args": {"ref": "drill", "owner": "$julien", "item": "Cordless drill", "borrower": "Ben"}},
    {"action": "Return", "subject": "drill", "args": {"owner": "$julien"}, "actor": "mallory"},
    {"action": "Return", "subject": "drill", "args": {"owner": "$julien"}},
    {"action": "Return", "subject": "drill", "args": {"owner": "$julien"}}
  ],
  "queries": [{"name": "Out", "params": {"owner": "$julien", "after": ""}}]
}

Expected: ✓ lent to Ana; ✗ lent twice; ✗ returned by a stranger; ✓ returned; ✗ returned twice; the query returns nothing.

From the command line

dhl-engine compile path/to/contract.dhl      # compiles, prints the artifact id
dhl-engine describe path/to/contract.dhl out # interfaces and the description (checks a UI file too)

In a repository

Contracts under contracts/ are compiled by the engine's tests, which also pin every contract's artifact id (a change you did not intend shows up as a changed id) and check that UI files leave artifacts unchanged. Add a test against a real node for contracts with composition (requires) or delegation.

Checklist

  • Every action checks context.signer.
  • Creating twice is refused (state.revision == 0).
  • Each status transition checks the current status.
  • Money is in minor units with a currency.
  • Merge rules are declared for actions used from several devices.
  • Queries filter by owner and page by a stable key.