Skip to main content
Tests live beside the code they cover and ship with it. There are two kinds: expect.* builds an assertion record and s.expect.* builds a statement. They are not interchangeable, and the types enforce it.

A unit test

Each entry is a named set of inputs run against that object:
Any statement can take a mock keyed by test name, which returns a value instead of doing its work while that one test runs:

A workflow test

A workflow test calls other objects and asserts on what they bind:
Register them with .registerFunctions([addNote]) and .registerWorkflowTests([addNoteWorks]).
Both kinds run against an empty datasource by default, so no seed rows exist while a test runs. Create what the test needs first (a function the stack calls), or mock the read. Setting datasource: "live" reads seed rows on an ephemeral, but the value is stored on the object: clear it before you promote, or the test clones your real database.

Run them

Tests run against what is deployed, so deploy first:
With no flag, test runs on the backend this project last deployed to. --on names another:
--on workspace runs against your real database. That is safe only while every test keeps the default empty datasource.

Deploy and test in one step

--test runs the suite after a deploy, against what it just shipped. This is the first step of the release flow:
--json (or a stdout that is not a terminal) prints one JSON document naming each test and its status, so CI can report which test failed. See CI/CD and exit codes.

Next