HTTP REQUESTS
SOAP Web Services
Test SOAP web services with native XML support, SOAPAction headers, namespace handling, and powerful XPath assertions for legacy enterprise systems.
Benefits of SOAP Testing
- No WSDL required: Test SOAP services without generating client code or stubs
- Native XML support: Write XML directly in feature files with embedded expressions
- Powerful XPath: Assert on response elements using XPath expressions
- Namespace handling: Configure namespace-aware parsing for complex SOAP messages
- Request flexibility: Inline XML or external files for cleaner test organization
Basic SOAP Request
Send SOAP requests using the soap action
keyword with inline XML envelopes.
Feature: Basic SOAP request
Scenario: Call SOAP service
Given url 'https://api.example.com/soap'
And request
"""
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUser xmlns="http://www.example.com/services/v1">
<UserId>12345</UserId>
</GetUser>
</soap:Body>
</soap:Envelope>
"""
When soap action 'GetUser'
Then status 200
The soap action
keyword automatically sets the SOAPAction
HTTP header with the specified value. This is required by most SOAP 1.1 services.
SOAP with External Files
Organize SOAP requests in separate XML files for better maintainability.
Feature: SOAP with external files
Scenario: Load SOAP request from file
Given url soapServiceUrl
And request read('classpath:soap-requests/get-user.xml')
When soap action 'GetUser'
Then status 200
And match response /Envelope/Body/GetUserResponse/User/Email == 'john.doe@example.com'
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUser xmlns="http://www.example.com/services/v1">
<UserId>12345</UserId>
</GetUser>
</soap:Body>
</soap:Envelope>
XPath Assertions
Validate SOAP responses using XPath expressions to extract and verify values.
Feature: XPath assertions on SOAP responses
Scenario: Validate SOAP response elements
Given url soapServiceUrl
And request read('get-billing-info.xml')
When soap action 'GetBillingInfo'
Then status 200
# Extract values using XPath
And match response /Envelope/Body/GetBillingInfoResponse/AccountBalance == '150.75'
And match response /Envelope/Body/GetBillingInfoResponse/Currency == 'USD'
And match response /Envelope/Body/GetBillingInfoResponse/Status == 'Active'
# Compare entire response section
And match response /Envelope/Body/GetBillingInfoResponse == read('expected-billing-response.xml')
Dynamic SOAP Requests
Use embedded expressions to create dynamic SOAP requests with variable data.
Feature: Dynamic SOAP requests
Scenario: Create user with dynamic data
* def userId = '67890'
* def userName = 'Alice Johnson'
* def userEmail = 'alice.johnson@example.com'
Given url soapServiceUrl
And request
"""
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<CreateUser xmlns="http://www.example.com/services/v1">
<User>
<Id>#(userId)</Id>
<Name>#(userName)</Name>
<Email>#(userEmail)</Email>
<Active>true</Active>
</User>
</CreateUser>
</soap:Body>
</soap:Envelope>
"""
When soap action 'CreateUser'
Then status 201
And match response /Envelope/Body/CreateUserResponse/Success == 'true'
And match response /Envelope/Body/CreateUserResponse/UserId == '#(userId)'
XML Namespace Handling
Handle complex SOAP messages with multiple namespaces using XPath with prefixes.
Feature: SOAP with namespaces
Scenario: Handle multiple namespaces
Given url soapServiceUrl
And request
"""
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:usr="http://www.example.com/user/v1"
xmlns:addr="http://www.example.com/address/v1">
<soap:Body>
<usr:GetUserDetails>
<usr:UserId>12345</usr:UserId>
<addr:IncludeAddress>true</addr:IncludeAddress>
</usr:GetUserDetails>
</soap:Body>
</soap:Envelope>
"""
When soap action 'GetUserDetails'
Then status 200
# XPath with namespace prefixes
And match response //usr:User/usr:Name == 'John Doe'
And match response //addr:Street == '123 Main St'
Namespace-Aware Configuration
Enable namespace-aware parsing for special cases where default handling fails.
Scenario: Configure namespace-aware parsing
# Enable for complex namespace scenarios
* configure xmlNamespaceAware = true
Given url soapServiceUrl
And request read('complex-soap-request.xml')
When soap action 'ComplexOperation'
Then status 200
Advanced XPath
Use XPath functions and dynamic expressions for complex SOAP response validation.
Feature: Advanced XPath operations
Scenario: XPath functions and node counting
Given url soapServiceUrl
And request read('get-order-items.xml')
When soap action 'GetOrderItems'
Then status 200
# Count nodes using XPath function
* match response count(/Envelope/Body/GetOrderItemsResponse/Items/Item) == 5
# Match attribute values
* match response //Item[@id='101']/Name == 'Widget A'
* match response //Item[@id='102']/Price == '29.99'
# Extract node-sets as arrays
* match response //Item[@category='electronics']/Name == ['Laptop', 'Mouse', 'Keyboard']
Dynamic XPath Expressions
Build XPath expressions dynamically using variables and the karate.xmlPath()
helper.
Scenario: Dynamic XPath evaluation
* def elementName = 'User'
* def fieldName = 'Email'
Given url soapServiceUrl
And request read('get-user.xml')
When soap action 'GetUser'
Then status 200
# Build XPath dynamically
* def xpath = '/Envelope/Body/GetUserResponse/' + elementName + '/' + fieldName
* def email = karate.xmlPath(response, xpath)
* match email == 'john.doe@example.com'
# Extract entire element
* def userElement = karate.xmlPath(response, '/Envelope/Body/GetUserResponse/' + elementName)
* match userElement contains { Email: 'john.doe@example.com' }
Common SOAP Patterns
SOAP Fault Handling
Validate SOAP fault responses for error scenarios.
Feature: SOAP fault handling
Scenario: Handle SOAP fault response
Given url soapServiceUrl
And request
"""
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUser xmlns="http://www.example.com/services/v1">
<UserId>invalid-id</UserId>
</GetUser>
</soap:Body>
</soap:Envelope>
"""
When soap action 'GetUser'
Then status 500
# Validate fault structure
And match response /Envelope/Body/Fault/faultcode == 'soap:Server'
And match response /Envelope/Body/Fault/faultstring == 'Invalid user ID'
And match response /Envelope/Body/Fault/detail/ErrorCode == 'USER_NOT_FOUND'
SOAP Authentication Headers
Add WS-Security or custom authentication headers to SOAP requests.
Feature: SOAP with authentication
Scenario: WS-Security username token
* def username = 'admin'
* def password = 'secret123'
Given url soapServiceUrl
And request
"""
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soap:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>#(username)</wsse:Username>
<wsse:Password>#(password)</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<GetSecureData xmlns="http://www.example.com/services/v1">
<DataId>12345</DataId>
</GetSecureData>
</soap:Body>
</soap:Envelope>
"""
When soap action 'GetSecureData'
Then status 200
Data-Driven SOAP Testing
Parameterize SOAP requests for testing multiple scenarios.
Feature: Data-driven SOAP testing
Scenario Outline: Test multiple users
* def userId = '<userId>'
* def expectedName = '<name>'
Given url soapServiceUrl
And request
"""
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetUser xmlns="http://www.example.com/services/v1">
<UserId>#(userId)</UserId>
</GetUser>
</soap:Body>
</soap:Envelope>
"""
When soap action 'GetUser'
Then status 200
And match response /Envelope/Body/GetUserResponse/User/Name == expectedName
Examples:
| userId | name |
| 101 | John Doe |
| 102 | Jane Smith |
| 103 | Bob Johnson |
Configuration Reference
SOAP-Specific Configuration
Configuration | Type | Default | Description |
---|---|---|---|
xmlNamespaceAware | boolean | false | Enable namespace-aware XML parsing for complex scenarios |
connectTimeout | integer | 30000 | Connection timeout in milliseconds |
readTimeout | integer | 30000 | Read timeout in milliseconds |
logPrettyRequest | boolean | false | Pretty print XML request in logs |
logPrettyResponse | boolean | false | Pretty print XML response in logs |
SOAP Action Keyword
When soap action '<SOAPAction>'
The soap action
keyword:
- Sets the
SOAPAction
HTTP header - Executes the HTTP POST request
- Replaces the
method post
step - Required for SOAP 1.1 services
Example Configuration
Feature: SOAP configuration
Background:
* url soapServiceUrl
* configure xmlNamespaceAware = true
* configure logPrettyRequest = true
* configure logPrettyResponse = true
* configure connectTimeout = 10000
* configure readTimeout = 10000
Scenario: Configured SOAP request
Given request read('soap-request.xml')
When soap action 'GetData'
Then status 200
Troubleshooting SOAP Requests
Common Issues
Problem: Namespace prefix not recognized in XPath
Solutions:
- Ensure namespace declarations are in SOAP envelope
- Enable
configure xmlNamespaceAware = true
- Use namespace prefixes consistently in XPath
Problem: SOAPAction header mismatch
Solutions:
- Verify SOAP action name matches WSDL operation
- Check SOAP service expects SOAP 1.1 (not SOAP 1.2)
- Review service documentation for correct action format
Problem: XML parsing errors
Solutions:
- Validate XML structure with online validator
- Check for unescaped special characters
- Enable
logPrettyRequest
to inspect actual request
Next Steps
Continue testing enterprise services:
- Handle XML responses: Response Handling
- Assert with XPath: Response Validation
- Parameterize requests: Dynamic Scenarios
- Organize SOAP files: Project Structure
- Configure timeouts: Configuration