Quick answer: Place assertions at every step of a scenario, checking the status, headers, or response fields each request returns, rather than asserting only the final response. Per-step assertions tell you exactly which request broke and keep a 200 status from masking a bad value. The engine evaluates them as the ordered flow runs and reports the failure against the step that failed.
Why one final assertion is not enough
If you only check the last response, a defect early in the flow can hide until the end, and the failure message tells you nothing about where it started. A token can be malformed at step one, an id can be wrong at step two, and the final call can fail for a reason that actually began several requests earlier.
Asserting at each step catches the problem where it occurs.
- Status assertions confirm the request returned the expected code.
- Header assertions check values such as content type or rate-limit headers.
- Field assertions verify the response body carries the expected values.
What per-step assertions look like
Each step in the ordered sequence carries its own checks, so the evidence reads as a trail rather than a single verdict.
| Step | Assertion focus | Failure meaning |
|---|---|---|
| Login | Status 200 and a token field present | Authentication did not produce a usable token |
| Create | Status 201 and an id returned | The resource was not created |
| Read | Status 200 and fields match the created id | The resource cannot be read back correctly |
| Update | Status 200 and the changed field reflects the edit | The change did not take effect |
When a step fails, the run stops or reports against that step, which keeps the diagnosis pointed instead of leaving you to walk the whole chain by hand.
Assert beyond the status code
A 200 is a weak assertion on its own, because a response can return 200 while carrying a wrong field or a body that breaks the contract. Assert the response fields that matter for the flow, not just the status, so a well-formed status with a bad value is caught.
- Assert the status to confirm the call was accepted.
- Assert the headers that later steps depend on.
- Assert the response fields, including the values a later step extracts.
- Confirm the extracted variable matches the expected shape.
The engine runs the connected requests in the main process with streamed progress, so you can watch each assertion evaluate as the step completes.
Limits and honest reading
Assertions only cover the fields and steps you define. A passing run says the asserted values held, not that every possible field is correct, and it does not prove the whole system is sound. Keep assertions focused on the values that carry the flow forward, and remember that an unasserted field carries no evidence.
Scenarios stay outside the OpenAPI document with no x-scenarios keys, and they run against real connected requests rather than mocks. A mock returning fixed answers cannot confirm the backend produces the asserted values.
Powerduck keeps the per-step assertions and their results visible in the run, so a failure names the request and the check that failed rather than presenting a single green or red label.
Frequently asked questions
Should every step assert the same things? No. Tailor the assertions to the step: login checks the token, create checks the new id, and read checks the fields. Each step asserts what the flow depends on.
Can a 200 still fail an assertion? Yes. A 200 status with a wrong or missing field fails a field assertion, which is why checking only the status is too weak.
What happens when a middle step fails? The run reports the failure against that step, so you can see the exact request and check that broke rather than only seeing the final call fail.
The bottom line
Multi-step flows need assertions at every step, not just at the end. Check status, headers, and the fields later steps rely on, assert beyond the status code so a 200 cannot mask a bad value, and let each failure name the exact request that broke. Per-step assertions turn a long chain into a diagnosable trail, while a single final check leaves you guessing where the defect really began. More in the API scenario testing guide.
Top comments (0)