Testing a flow

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.

A test run from the editor

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:

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.

Fixtures

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.

What a fixture may contain

KeyMeaning
payloadThe trigger payload for this run
metaThe delivery sidecar
inputInput values for this run, replacing the deployment's
from, to, stepsRun only part of the flow
versionRun a published version number instead of the draft
expectWhat 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.

Naming connections and data stores

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" } } }

Statuses are the platform's words

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.

Checking before you run anything

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.

Replaying a real run

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 slow case is not a hung CLI

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.

Next