Testing Asynchronous Flows
A common challenge in modern API testing is handling asynchronous operations—actions that start a background job and return a response immediately, while the work is completed later. Examples include video processing, report generation, or triggering a complex calculation.
Testing these flows requires a polling strategy, where you repeatedly check the status of the job until it’s complete.
The Polling Pattern
This pattern is a straightforward and reliable way to test asynchronous APIs. It typically involves three stages.
Stage 1: Start the Asynchronous Job
-
API Node: Trigger the JobPOST /reports- The API responds immediately with a
202 Acceptedand a job ID. - Response Body:
{ "jobId": "job-abc-123", "status": "PENDING" }
-
Context Operation:- Save the
jobIdfrom the response body into a context variable:context.jobId = response.body.jobId.
- Save the
Stage 2: Poll for Completion using a Loop
-
Loop Node:- Type:
REPEAT - Times:
10(A reasonable maximum number of attempts) - Delay:
5000(Wait 5 seconds between each attempt) breakCondition(JSONata):response.body.status === 'COMPLETED'
- Type:
-
Child
API Node(inside the Loop):API Node: Get Job StatusGET /reports/{{jobId}}- This node will be called repeatedly. After each call, the
breakConditionon the parent Loop Node is checked. The loop will stop as soon as the status is'COMPLETED', or after 10 attempts.
Stage 3: Assert the Final Result
-
API Node: Get the Final Report Data- This step runs after the loop has successfully completed.
GET /reports/{{jobId}}/data- Now that the job is complete, you can fetch the final result.
-
Assertions:
- Assert that the final report data is correct. For example,
response.body.revenue === 1000.
- Assert that the final report data is correct. For example,
This pattern provides a robust way to test asynchronous workflows by ensuring your test waits for the background process to finish before it tries to validate the final outcome.