SOAP and XML load testing
SOAP (Simple Object Access Protocol) is an XML messaging protocol used in enterprise web services. Many organizations still run SOAP services in finance, healthcare, and government systems. SOAP is HTTP POST with an XML body, so MaxoPerf load-tests it with the same HTTP mechanisms you use for REST.
Before you start
Section titled “Before you start”- Read HTTP and REST load testing. SOAP load testing is a special case of HTTP POST.
- Get the WSDL for the service you test. It gives you the endpoint URL, action headers, and message structure.
SOAP over HTTP
Section titled “SOAP over HTTP”SOAP requests are HTTP POST requests with:
Content-Type: text/xml; charset=utf-8(SOAP 1.1) orapplication/soap+xml(SOAP 1.2).- A
SOAPActionheader identifying the operation (SOAP 1.1 only). - An XML SOAP envelope in the request body.
The response is a 200 OK with an XML SOAP envelope body, or a 500 with a SOAP Fault envelope when the operation fails.
Taurus native HTTP for SOAP
Section titled “Taurus native HTTP for SOAP”execution: - concurrency: 20 ramp-up: 30s hold-for: 5m scenario: soap-account-service
scenarios: soap-account-service: default-address: https://services.example.com requests: - label: GetAccountBalance url: /AccountService method: POST headers: Content-Type: text/xml; charset=utf-8 SOAPAction: "http://example.com/AccountService/GetAccountBalance" body: | <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acc="http://example.com/AccountService"> <soap:Header/> <soap:Body> <acc:GetAccountBalance> <acc:AccountId>${account_id}</acc:AccountId> </acc:GetAccountBalance> </soap:Body> </soap:Envelope> assert: - equals: subject: http-code value: '200' - not-contains: subject: body value: '<soap:Fault>'
- label: TransferFunds url: /AccountService method: POST headers: Content-Type: text/xml; charset=utf-8 SOAPAction: "http://example.com/AccountService/TransferFunds" body: | <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acc="http://example.com/AccountService"> <soap:Header> <acc:AuthToken>${session_token}</acc:AuthToken> </soap:Header> <soap:Body> <acc:TransferFunds> <acc:FromAccount>${account_id}</acc:FromAccount> <acc:ToAccount>TARGET-001</acc:ToAccount> <acc:Amount>100.00</acc:Amount> </acc:TransferFunds> </soap:Body> </soap:Envelope> assert: - not-contains: subject: body value: '<soap:Fault>'Asserting for SOAP faults
Section titled “Asserting for SOAP faults”SOAP errors return HTTP 200 with a <soap:Fault> element in the body (SOAP 1.1) or HTTP 500. Add a not-contains assertion for <soap:Fault> to catch application-level errors:
assert: - not-contains: subject: body value: '<soap:Fault>'k6 for SOAP
Section titled “k6 for SOAP”k6 sends SOAP requests with its http.post() function, the SOAP headers, and an XML body string:
import http from 'k6/http';import { check } from 'k6';
const SOAP_URL = 'https://services.example.com/AccountService';
function buildGetBalanceEnvelope(accountId) { return `<?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acc="http://example.com/AccountService"> <soap:Header/> <soap:Body> <acc:GetAccountBalance> <acc:AccountId>${accountId}</acc:AccountId> </acc:GetAccountBalance> </soap:Body></soap:Envelope>`;}
export const options = { vus: 20, duration: '5m',};
export default function () { const accountId = 'ACC-0001';
const res = http.post( SOAP_URL, buildGetBalanceEnvelope(accountId), { headers: { 'Content-Type': 'text/xml; charset=utf-8', SOAPAction: '"http://example.com/AccountService/GetAccountBalance"', }, tags: { name: 'GetAccountBalance' }, // shows in per-endpoint breakdown } );
check(res, { 'status 200': (r) => r.status === 200, 'no soap fault': (r) => !r.body.includes('<soap:Fault>'), 'balance present': (r) => r.body.includes('<acc:Balance>'), });}SOAP 1.2 differences
Section titled “SOAP 1.2 differences”SOAP 1.2 uses a different namespace and content type:
| Aspect | SOAP 1.1 | SOAP 1.2 |
|---|---|---|
| Envelope namespace | http://schemas.xmlsoap.org/soap/envelope/ | http://www.w3.org/2003/05/soap-envelope |
| Content-Type | text/xml; charset=utf-8 | application/soap+xml; charset=utf-8 |
| SOAPAction header | Required | Optional (moved to Content-Type parameter) |
| Fault element | <soap:Fault> | <soap12:Fault> |
Update your assertions to match:
assert: - not-contains: subject: body value: '<soap12:Fault>' # SOAP 1.2 fault element nameParameterizing SOAP with CSV data
Section titled “Parameterizing SOAP with CSV data”When each VU needs its own account IDs, transaction amounts, or user credentials, use a CSV data entity in MaxoPerf:
scenarios: parameterized-soap: data-sources: - path: accounts.csv variable-names: account_id, session_token
requests: - label: GetBalance url: /AccountService method: POST headers: Content-Type: text/xml; charset=utf-8 SOAPAction: "http://example.com/AccountService/GetAccountBalance" body: | <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <GetAccountBalance xmlns="http://example.com/AccountService"> <AccountId>${account_id}</AccountId> </GetAccountBalance> </soap:Body> </soap:Envelope>See Cookbook: CSV data-driven test for the full CSV setup.
Reading SOAP results in MaxoPerf
Section titled “Reading SOAP results in MaxoPerf”SOAP results appear in the standard HTTP result view. Label each operation with label: (Taurus) or tags: { name: '…' } (k6) so the per-endpoint breakdown shows one row per SOAP operation instead of all requests under the /AccountService URL.
Watch for:
- Error rate spike: often
<soap:Fault>responses. Check the captured response samples on the Errors tab. - Latency increase: XML parsing costs more CPU than JSON. Under high concurrency the server’s XML parser can become the bottleneck and latency rises.
Do / don’t
Section titled “Do / don’t”Do:
- Assert on
<soap:Fault>in the response body as well as the HTTP status. Many SOAP faults are HTTP 200. - Give each SOAP operation its own label so the MaxoPerf per-endpoint panel shows one row per operation.
- Use MaxoPerf secrets for auth tokens that appear in the SOAP header.
Don’t:
- Use XML entities that could trigger XXE parsing. MaxoPerf’s bundle assembler rejects unsafe paths, but the target SOAP service may be vulnerable.
- Include real customer account IDs or financial data in uploaded test files. Use synthetic test data.
Where to go next
Section titled “Where to go next”- HTTP and REST load testing: the base HTTP patterns.
- Cookbook: CSV data-driven test: parameterize with CSV account data.
- Cookbook: correlation / dynamic values: extract session tokens from SOAP login responses.
- By engine index: back to the engine overview.