Best Practices & Examples
Real-world flow examples and strategies for building effective, maintainable flows.
Example: Authentication Flow
A 3-step flow that logs in, fetches the user profile, and updates it. Demonstrates token extraction and reuse across steps.
URL: {{base_url}}/api/auth/login
Body:
Extractions (post-response script):
| Name | Source | Expression |
|---|---|---|
| token | JSON Path | data.accessToken |
| refreshToken | JSON Path | data.refreshToken |
| userId | JSON Path | data.user.id |
URL: {{base_url}}/api/users/{{flow.userId}}
Headers:
Assertions (Processors tab):
✓ Status code equals 200
✓ Body JSON data.id equals {{flow.userId}}
Extractions:
| Name | Source | Expression |
|---|---|---|
| username | JSON Path | data.username |
URL: {{base_url}}/api/users/{{flow.userId}}
Headers:
Body:
Assertions:
✓ Status code equals 200
✓ Body JSON data.displayName equals Updated Name
Key takeaway: {{base_url}}, {{email}}, and {{password}} come from the group environment (static, reusable). {{flow.token}}, {{flow.userId}}, and {{flow.username}} come from response extractions (dynamic, per-run).
Example: Order Management Flow
A 4-step CRUD flow that creates an order, retrieves it, updates the quantity, and finally cancels it. Demonstrates the Setup → Test → Teardown pattern.
URL: {{base_url}}/api/orders
Headers: Authorization: Bearer {{flow.token}}
Body:
Extractions:
| Name | Source | Expression |
|---|---|---|
| orderId | JSON Path | data.id |
| orderStatus | JSON Path | data.status |
Assertions: Status code equals 201
URL: {{base_url}}/api/orders/{{flow.orderId}}
Headers: Authorization: Bearer {{flow.token}}
Assertions:
✓ Status code equals 200
✓ Body JSON data.id equals {{flow.orderId}}
✓ Body JSON data.status equals pending
✓ Body JSON data.quantity equals 2
URL: {{base_url}}/api/orders/{{flow.orderId}}
Headers: Authorization: Bearer {{flow.token}}
Body:
Assertions:
✓ Status code equals 200
✓ Body JSON data.quantity equals 5
URL: {{base_url}}/api/orders/{{flow.orderId}}
Headers: Authorization: Bearer {{flow.token}}
Assertions: Status code equals 200 or 204
Key takeaway: The {{flow.token}} here is assumed to come from a previous Auth flow run, or from a Login step you add at the beginning. In a real setup, you'd either prepend a Login step or use tg.flow.set() in a pre-script to set the token. The last step (Cancel) acts as teardown to keep the database clean for re-runs.
Example: Payment Processing Flow
A 3-step flow that creates a payment intent, confirms the payment, and verifies the final state. Shows how multiple extractions chain through the flow.
URL: {{base_url}}/api/payments/intent
Headers: Authorization: Bearer {{flow.token}}
Body:
Extractions:
| Name | Source | Expression |
|---|---|---|
| paymentId | JSON Path | data.id |
| clientSecret | JSON Path | data.clientSecret |
Assertions: Status code equals 201, Body JSON data.status equals requires_confirmation
URL: {{base_url}}/api/payments/{{flow.paymentId}}/confirm
Headers: Authorization: Bearer {{flow.token}}
Body:
Extractions:
| Name | Source | Expression |
|---|---|---|
| transactionId | JSON Path | data.transactionId |
Assertions: Status code equals 200, Body JSON data.status equals succeeded
URL: {{base_url}}/api/payments/{{flow.paymentId}}
Headers: Authorization: Bearer {{flow.token}}
Assertions:
✓ Status code equals 200
✓ Body JSON data.status equals succeeded
✓ Body JSON data.amount equals 9999
✓ Body JSON data.transactionId equals {{flow.transactionId}}
Key takeaway: Notice how data chains through: Step 1 extracts paymentId and clientSecret, Step 2 uses both and extracts transactionId, Step 3 verifies using paymentId from Step 1 and transactionId from Step 2. Each step builds on the data from previous steps.
Flow Organization
- •Group by domain: Create flow groups per API or service (e.g., "Auth API", "Payment API", "User API")
- •Name flows descriptively: Use action-oriented names like "User Registration Flow" or "Order Checkout Sequence" instead of generic names
- •Name steps clearly: Each step name should describe its purpose (e.g., "Create User" instead of "Step 1")
- •Keep flows focused: A flow should test one scenario or workflow. Prefer multiple small flows over one large flow.
Variable Strategy
- •Use {{flow.varName}} for dynamic data: Tokens, IDs, timestamps, and anything that comes from a response should use the flow prefix
- •Use {{varName}} for config: Base URLs, API keys, and static configuration belong in group environments
- •Extract early: Set up extractions in the first steps that produce values needed later (e.g., auth tokens, resource IDs)
- •Use meaningful names: Name variables based on their purpose — authToken instead of var1
- •Prefer JSON Path: For structured JSON responses, JSON Path extraction is the most reliable and readable
- •Use regex sparingly: Reserve regex extraction for non-JSON responses or complex patterns that JSON Path can't handle
Environment Usage
- •Use environments for base URLs: Store {{base_url}} in environments so the same flow works against dev, staging, and production
- •Mark secrets as secret: Always use the secret flag for API keys, passwords, and tokens to prevent accidental exposure
- •Store test credentials: Keep test user credentials (email, password) in environments so flows are rerunnable without editing steps
Linear vs Visual Mode
| Scenario | Recommended Mode | Why |
|---|---|---|
| Simple API sequence | Linear | Steps run in order, no branching needed |
| CRUD test suite | Linear | Create → Read → Update → Delete is naturally sequential |
| Conditional logic | Visual | Branch based on response status or data |
| Parallel requests | Visual | Independent branches execute concurrently |
| Complex workflow | Visual | Easier to understand flow structure at a glance |
Execution Tips
- •Test steps individually first: Use the Send button on each step to verify it works before running the entire flow
- •Use "Stop on Failure" during development: This helps you find and fix the first broken step without noise from subsequent failures
- •Disable "Stop on Failure" for regression: When running regression tests, let all steps execute to get the full picture of what's passing and failing
- •Use iterations for stability: Run 5-10 iterations to catch intermittent failures or performance regressions
- •Add delays for rate-limited APIs: If an API has rate limits, use the delay option to space out requests
Step Design
- •One action per step: Each step should do one thing. Don't try to combine multiple operations into a single request.
- •Add assertions: Use the Processors tab to add assertions that validate response status, body content, and headers. This turns your flows into automated tests.
- •Configure retries for flaky endpoints: If a step calls an unreliable service, set up retry behavior instead of re-running the entire flow.
- •Disable non-essential steps: Use the enable/disable toggle to temporarily skip steps during debugging without deleting them.