Quick answer: A scanned OpenAPI document gives you proven routes and classified contracts to build scenario tests from, instead of starting with a hand-written or guessed spec. You then order the requests into a flow, extract values between steps, and assert at each stage. The scan rebuilds the contract from code, and the scenario verifies the connected behavior the scan itself cannot prove.

Why the order matters

A scan and a scenario answer different questions. The scan tells you which routes exist and what shapes they declare, while the scenario tells you whether the connected flow works. Treating the scan as the end of verification would leave runtime behavior untested, since the scan does not run the app.

Using the scanned spec as the input keeps the scenario grounded in real routes rather than invented paths.

From scan to scenario

Stage What you get Purpose
Scan Proven routes and gate status Establish the real surface
Review Mounted, reachable routes Confirm what can be called
Scenario Ordered requests with extracted variables Model the business flow
Assertions Per-step checks Verify the connected behavior
Report Self-contained HTML record Share the evidence

The scenario is never stored in the OpenAPI document, with no x-scenarios keys, so the spec and the test stay separate.

Building the flow from detected routes

Once the routes are confirmed, chain them the way the business flow runs.

  1. Pick the routes that make up the flow, such as login, create, and read.
  2. Order them so each extraction precedes the step that needs it.
  3. Extract a token or id from one response and pass it into the next request.
  4. Assert status, headers, and fields at every step.
  5. Run the connected requests against the real backend, not a mock.

The engine runs the scenario in the main process with streamed progress and a cancel action, so you can watch the flow and stop a hung run.

Take a user onboarding flow. The scan proves the auth, profile, and preferences routes and marks each contract. After confirming they are mounted, you chain them in order: the auth step returns a token, the profile step uses it and returns a user id, and the preferences step writes against that id. A field assertion on the final read confirms the profile data matches what the earlier steps created. If the preferences step silently drops a value, the scan never sees it, but the assertion on the executed chain fails and the report points at that exact step rather than the whole flow.

What the scenario adds beyond the scan

This is where the gap from the scan gets closed. A route can be detected and emitted with a correct contract yet still break at runtime, and a 200 response can carry a field that breaks the contract or a later step. The scenario catches those failures by executing the chain and asserting the values, rather than trusting the static document.

A passing run covers only the flow you defined, not every path, and it does not prove the whole system is correct. Keep separate scenarios for the alternate branches, and treat an unexercised route as unverified.

Powerduck connects the two core workflows so the scanned spec feeds directly into the scenario engine, with the per-step evidence kept together.

Frequently asked questions

Does a scanned spec already verify the behavior? No. The scan rebuilds the contract from code but does not run the app. You build scenario tests from it to verify the connected flow.

Can I build scenarios on unmounted routes? No. Confirm the routes are mounted and reachable first, since an unmounted router cannot be called.

What does the scenario catch that the scan cannot? Runtime breaks across the chain, including a 200 with a bad field and a value that a later step rejects, because the scenario executes real requests.

The bottom line

A scanned spec is the reliable input for scenario testing, not the verification itself. Build ordered flows from the proven, reachable routes, pass values between steps, and assert at each stage against the real backend. This closes the runtime gap the scan cannot reach, while a passing run still covers only the defined flow. The two core workflows fit together: the scan rebuilds the contract, and the scenario proves the behavior. Continue in the code-to-OpenAPI guide.