Worked Examples
Cases files pin a blueprint to figures worked out by hand, so a change that breaks one fails before anyone relies on it.
After reading this guide, you will know:
- What a cases file holds, and how
rmt testreads it. - How expected values are compared: numbers by value, rows by the columns listed.
- What a failing case reports, and what makes a case unable to run.
- How to run the same cases from your own specs.
Why Cases Come First
A blueprint is only as good as the figures it is proven against. Write the worked examples before the blueprint, from the figures the source gives where it gives them, and work others out by hand. Say how in a comment. Then write the blueprint until every case passes, and change a case only when it was worked out wrongly.
The shipped blueprints all work this way: each is proven by its own cases.
The Format
A cases file is a YAML list. Each case has:
| Key | Holds |
|---|---|
name |
what the case shows, in words |
facts |
the facts to run, as for rmt run |
expect |
the outputs it should give: any of them, not necessarily all |
calculation |
optional: the calculation to run, when it is not the first |
# Worked by hand from the prices and loyalty tables in membership.yml.
- name: numbers compare by value, so 11, 11.00 and '11' all match
facts: {plan: basic, renews_on: 2026-06-30, visits: 4}
expect: {price: '11', charge: 11.00}
- name: expect may list only some of the outputs
facts: {plan: premium, renews_on: 2026-11-02, visits: 75}
expect: {tier: gold}
- name: rows match on the columns the case lists
calculation: every_plan
facts: {renews_on: 2026-07-01, visits: 75}
expect:
quotes:
- {plan: basic, charge: 11.25}
- {plan: premium, charge: 18}
The blueprint is the one from Tables and Lookups.
$ rmt test membership.yml membership_cases.yml
✓ 3 cases passed
How Values Compare
- Numbers compare by value.
7,7.00and'7'all match 7, so write figures the way the source does. - Rows compare on the columns the case lists. A row in the result may have more columns than the case names.
- Lists compare item by item, and must be the same length.
- Everything else must be equal: text,
trueandfalse, dates.
When a Case Fails
test runs every case and reports each difference, and each case that could not run:
$ rmt test membership.yml mistakes_cases.yml
✗ 5 of 5 cases failed
✗ a wrong figure
charge: expected 11.87, got 11.88
✗ a list of rows must have as many rows as the result
quotes: expected [{plan: "basic", charge: "11.25"}], got [{plan: "basic", price: "12.5", tier: "gold", charge: "11.25"}, {plan: "premium", price: "20", tier: "gold", charge: "18"}]
✗ facts the calculation refuses
fact plan should be one of basic, premium, not "gold". facts need visits
✗ a case without expect
case a case without expect needs expect, the outputs it should produce
✗ a misspelt key
case a misspelt key does not take fatcs; cases take name, facts, expect, calculation
$ echo $?
3
In JSON, each failing output is {output, expected, actual} and a case that could not run has an
error:
{
"passed": 0,
"failed": 5,
"cases": [
{
"name": "a wrong figure",
"passed": false,
"differences": [
{
"output": "charge",
"expected": "11.87",
"actual": "11.88"
}
]
},
...
]
}
A cases file that is not valid YAML is a problem with exit 2, as a blueprint’s would be:
✗ 1 problem
• The cases file is not valid YAML: (<unknown>): did not find expected ',' or ']' while parsing a flow sequence at line 1 column 9
test checks the blueprint first. A blueprint with problems is reported as check reports it, and no
case runs.
Cases in Your Build
Keep the worked examples as the contract, so a change to the rules that breaks a hand-worked case fails the build:
rmt test blueprint.yml cases.yml # exit 3 when a case fails
rmt push quote blueprint.yml cases.yml && rmt publish quote
Cases Elsewhere
- The hosted service runs a definition’s cases on every push and refuses to publish a draft with a failing case. See The Hosted Service.
Next Steps
- Chaining with Imports and Runs - Test each link of a chain on its own.
- CLI Commands and Exit Codes - Everything
testprints, and its exit codes.