You test a flow by running its draft source on the real platform. There is no local simulator: a test run uses the same worker, the same limits and the same connections a deployment would, so what passes here is what will happen.
The editor's run action executes the current draft against a payload you supply. It produces a real execution you can open, with steps, logs and results like any other.
Two differences from a production run, both deliberate:
subscribers: 0.You can also scope a run to part of the flow: start at a step, stop at a step, or run a named subset. That is how you re-test step four without paying for steps one to three again.
The editor can also attach a debugger to that run — breakpoints, stepping and a live call stack against the real worker. See Debugging in the editor.
A fixture is one JSON file in flows/<name>/tests/, run by konnecthub test. Fixtures are
yours: they are never pushed to the draft and never pulled over.
{
"payload": { "id": "A-1001", "total": 42.5 },
"input": { "region": "eu", "crm": { "$connection": "Acme CRM" } },
"expect": {
"status": "SUCCEEDED",
"steps": { "readOrder": "SUCCEEDED" },
"output": { "seen": true }
}
}
konnecthub test # every fixture of every linked flow
konnecthub test order-received # one flow
konnecthub test --case happy-path # one fixture
Each fixture runs as a draft run and its outcome is compared to expect. The command exits 1
if any case fails, and prints every mismatch rather than stopping at the first.
| Key | Meaning |
|---|---|
payload | The trigger payload for this run |
meta | The delivery sidecar |
input | Input values for this run, replacing the deployment's |
from, to, steps | Run only part of the flow |
version | Run a published version number instead of the draft |
expect | What should have happened |
expect holds status (default SUCCEEDED), steps as a { step: status } map, output, and
error — a string to look for in the failure.
A fixture is committed to git, so it cannot hold ids. Name the resource instead and the CLI resolves it:
{ "input": { "crm": { "$connection": "Acme CRM" }, "table": { "$dataStore": "customers" } } }
expect.status must be a real ExecutionStatus: SUCCEEDED, FAILED, CANCELLED, PAUSED
and so on. There is no COMPLETED, and near-misses are refused rather than translated: a common
one (COMPLETED, OK, ERROR) is rejected with the platform's own word named in the error, and
anything else is rejected against the full list — so a fixture never asserts a status that cannot
occur, and never passes under a word the platform does not use.
Step statuses are narrower: RUNNING, SUCCEEDED, FAILED, WAITING_RERUN. Use "*" to
assert a step ran without pinning its status.
konnecthub check
Validates the flow locally — no network, so it works when everything else refuses. It also
typechecks through the generated resolver, which maps konnecthub/flow and your workspace
libraries onto real declarations.
When something failed in production, you rarely want a synthetic payload — you want that one. Replaying an execution re-runs it against the same recorded event, and you can scope the replay to the step that failed.
That is also why a fixture can name a version: reproducing a failure means running the code
that failed, not the draft you have since edited.
A fixture that expects a boot failure takes around 60 seconds — a flow whose source cannot even start is proven only by waiting for the platform to give up on it. Every other case is a second or two.