Skip to main content

HTTP REQUESTS

Polling and Async

Handle asynchronous operations with retry until - enabling robust polling for async APIs, job processing, and eventual consistency testing.

Benefits of Retry Until

  • No manual loops: Built-in polling eliminates boilerplate retry code
  • Declarative syntax: Express retry conditions as simple JavaScript expressions
  • Configurable timing: Adjust retry count and intervals per scenario or globally
  • Robust async testing: Handle eventual consistency and long-running operations reliably

Simple Retry Pattern

Wait for a condition with automatic retrying:


Scenario: Poll until job completes
* configure retry = { count: 10, interval: 2000 }

Given url baseUrl
And path 'jobs', jobId
And retry until response.status == 'completed'
When method get
Then status 200
And match response.result == '#object'
Key Points
  • Default retry is 3 attempts with 3-second intervals
  • Retry conditions must be pure JavaScript expressions
  • Use configure retry to customize behavior

Retry with Multiple Conditions

Combine conditions using JavaScript operators:


Scenario: Wait for processing and validation
* configure retry = { count: 15, interval: 3000 }

Given url baseUrl
And path 'processing/status'
And retry until responseStatus == 200 && response.progress >= 100
When method get
Then status 200
And match response.status == 'success'

Retry with Data Validation

Wait for complex data conditions:


Scenario: Wait for aggregation completion
* configure retry = { count: 20, interval: 2000 }

Given url baseUrl
And path 'data/aggregation'
And param dataset = 'users'
And retry until responseStatus == 200 && response.totalRecords > 0
When method get
Then match response.totalRecords == '#number'
And match response.data == '#[]'

Retry Configuration

Customize retry behavior per scenario or environment:


Scenario: Environment-specific retry
* def env = karate.env || 'dev'
* def retryConfig = env == 'prod' ?
{ count: 30, interval: 5000 } : # Patient in prod
{ count: 10, interval: 1000 } # Fast in dev

* configure retry = retryConfig

Given url baseUrl
And path 'jobs', jobId
And retry until response.status != 'pending'
When method get
Then status 200

Job Processing Workflows

Handle async job lifecycle from submission to completion:


Scenario: Complete async job workflow
# Step 1: Submit job
Given url baseUrl
And path 'jobs/submit'
And request { type: 'image-processing', input: 'image.jpg' }
When method post
Then status 202
* def jobId = response.jobId

# Step 2: Poll for completion
* configure retry = { count: 30, interval: 2000 }
Given path 'jobs', jobId
And retry until response.status == 'completed'
When method get
Then status 200
And match response.result.outputUrl == '#string'

Event-Driven Testing

Test event-driven systems and webhooks:


Scenario: Wait for webhook delivery
* def webhookUrl = 'https://webhook.site/unique-id'

# Trigger action that sends webhook
Given url baseUrl
And path 'notifications/send'
And request { type: 'user-created', userId: 123, webhookUrl: '#(webhookUrl)' }
When method post
Then status 200

# Poll webhook endpoint for delivery
* configure retry = { count: 20, interval: 3000 }
Given url webhookUrl
And retry until response != null && response.type == 'user-created'
When method get
And match response.userId == 123

Error Handling with Retry

Handle multiple outcomes in retry conditions:


Scenario: Retry with error recovery
* configure retry = { count: 25, interval: 2000 }

Given url baseUrl
And path 'unstable/service'
And retry until responseStatus == 200 || responseStatus == 404
When method get

# Handle different outcomes
* if (responseStatus == 200) karate.log('Success')
* if (responseStatus == 404) karate.fail('Resource not found')

Advanced Retry Patterns

Custom retry logic with conditional handling:


Scenario: Retry until error resolved
* configure retry = { count: 20, interval: 1500 }

Given url baseUrl
And path 'eventually-consistent/endpoint'
And retry until responseStatus < 500
When method get
Then status 200
And match response.data == '#present'
Performance Considerations
  • Long polling increases test execution time significantly
  • Configure retry globally in karate-config.js for consistent behavior
  • Consider timeout settings when working with slow services

Next Steps