SOAP and XML load testing
SOAP (Simple Object Access Protocol) is an XML-based messaging protocol used in enterprise web services. Despite its age, many organizations still run SOAP-based services in finance, healthcare, and government systems. MaxoPerf can load-test SOAP services using the same HTTP mechanisms you use for REST — SOAP is HTTP POST with an XML body.
Before you start
Section titled “Before you start”- Read HTTP and REST load testing — SOAP load testing is a specialization of HTTP POST.
- Obtain the WSDL for the service you are testing to understand 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 always 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 can send SOAP requests using its http.post() function with the appropriate 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 accordingly:
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”For tests that need different account IDs, transaction amounts, or user credentials per VU, 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 distinct rows for each SOAP operation rather than all requests lumped under the /AccountService URL.
Watch for:
- Error rate spike — often indicates
<soap:Fault>responses; check the Log tab for response bodies. - Latency increase — XML parsing is more CPU-intensive than JSON; latency may increase under high concurrency as the server’s XML parser becomes a bottleneck.
Do / don’t
Section titled “Do / don’t”Do:
- Assert for
<soap:Fault>in the response body, not just HTTP status — many SOAP faults are HTTP 200. - Label each SOAP operation distinctly so the MaxoPerf per-endpoint panel shows meaningful breakdown.
- Use MaxoPerf secrets for auth tokens that appear in the SOAP header.
Don’t:
- Use XML entities that could trigger XXE parsing — MaxoPerf’s own 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 foundational 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 — return to the engine overview.