SoapUI Tutorial: SOAP Web Service Testing Step by Step

SoapUI Tutorial: SOAP Web Service Testing Step by Step

Banks, insurers, airlines, telecom operators and government systems still run on SOAP web services, and SoapUI is the tool their QA teams use to test them. In this SoapUI tutorial you’ll install SoapUI, import a real WSDL, send SOAP requests, add assertions (including XPath and SOAP Fault checks), build a test suite and even find a real bug in a public SOAP service. No coding needed.

Quick answerSoapUI is an open-source tool for testing SOAP and REST APIs. For SOAP testing you create a project from a WSDL; SoapUI generates a request template for every operation. You fill in values, send the request and add assertions such as SOAP Response, Not SOAP Fault, Contains, XPath Match, Schema Compliance and Response SLA. Requests are organised as Project → TestSuite → TestCase → TestStep, and suites can run from the command line with testrunner. ReadyAPI is the paid version with extra features.
Advertisement

Where You’ll Meet SOAP in Real Projects

Real-life examples Banking: core banking systems expose operations like GetAccountBalance and FundTransfer to the mobile banking middleware. Insurance: agent portals call CreateQuote and IssuePolicy. Telecom: billing systems expose GetBillSummary. Travel: airline reservation systems and GDS integrations. Many of these were built 10 to 20 years ago and are still business-critical.

Service companies working for these clients regularly ask for “SoapUI” in QA job descriptions. If you’ve only tested REST, this lesson closes the gap. Background: REST vs SOAP vs GraphQL.

Key SOAP Terms Before You Start

TermMeaning
WSDLWeb Services Description Language: the XML contract listing operations, messages, types and the endpoint URL
OperationA function the service offers, e.g. Add, GetBalance
Envelope / Header / BodyThe parts of every SOAP message
SOAP FaultThe standard error element inside Body (faultcode, faultstring, detail)
BindingHow messages are sent: SOAP 1.1 or SOAP 1.2
NamespaceA URI that qualifies element names, e.g. xmlns:tem="http://tempuri.org/"
SOAPActionHTTP header (SOAP 1.1) naming the operation
XSDXML Schema defining the data types
Advertisement

Step 1: Install SoapUI

  1. Download SoapUI Open Source from soapui.org (Windows, macOS, Linux). It’s free; ReadyAPI is the commercial edition.
  2. Install and launch it. The left panel is the Navigator (project tree); the main area opens editors for requests and tests.
SoapUI vs ReadyAPI Open source covers everything in this course: SOAP and REST requests, assertions, test suites, properties, Groovy scripts, data-driven loops (with a little scripting) and command-line runs. ReadyAPI adds point-and-click DataSource steps, richer reports, service virtualisation and team features.

Step 2: Create a SOAP Project from a WSDL

We’ll use a free public demo calculator service:

http://www.dneonline.com/calculator.asmx?WSDL
  1. File → New SOAP Project.
  2. Project name: Calculator. Initial WSDL: paste the URL above.
  3. Keep Create Requests ticked. Click OK.
  4. SoapUI reads the WSDL and creates two bindings, CalculatorSoap (SOAP 1.1) and CalculatorSoap12 (SOAP 1.2), each with four operations: Add, Subtract, Multiply, Divide, and a sample request “Request 1” under each.

Public demo services can be slow or occasionally offline. If it doesn’t respond, try again later; the steps are identical for your company’s WSDL.

Step 3: Send Your First SOAP Request

Expand CalculatorSoap → Add and double-click Request 1. SoapUI generated this template:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:Add>
         <tem:intA>?</tem:intA>
         <tem:intB>?</tem:intB>
      </tem:Add>
   </soapenv:Body>
</soapenv:Envelope>

Replace the ? with 5 and 7, then click the green Submit arrow. The response:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" ...>
   <soap:Body>
      <AddResponse xmlns="http://tempuri.org/">
         <AddResult>12</AddResult>
      </AddResponse>
   </soap:Body>
</soap:Envelope>

Use the tabs on the response side: XML (body), Raw (HTTP status and headers: HTTP/1.1 200 OK, Content-Type: text/xml) and the time in milliseconds at the bottom.

The same call with cURL, so you see what SoapUI sends under the hood:

curl -i -X POST "http://www.dneonline.com/calculator.asmx" \
  -H "Content-Type: text/xml; charset=utf-8" \
  -H 'SOAPAction: "http://tempuri.org/Add"' \
  -d '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"><soapenv:Body><tem:Add><tem:intA>5</tem:intA><tem:intB>7</tem:intB></tem:Add></soapenv:Body></soapenv:Envelope>'
SOAP 1.1 vs 1.2 on the wire SOAP 1.1 uses Content-Type: text/xml plus a separate SOAPAction header. SOAP 1.2 uses Content-Type: application/soap+xml; action="..." and the namespace http://www.w3.org/2003/05/soap-envelope. Try the same operation under CalculatorSoap12 to see the difference in the Raw tab.
Advertisement

Step 4: Build a Test Suite

Requests under the interface are for exploring. Real tests live in test suites:

  1. Right-click the Add request → Add to TestCase → create TestSuite Calculator Regression and TestCase Add - positive.
  2. The request becomes a TestStep. Add more steps for Subtract, Multiply and Divide the same way.
LevelExampleHolds
ProjectCalculatorInterfaces (WSDL), test suites, project properties
TestSuiteCalculator RegressionRelated test cases
TestCaseDivide – negativeOrdered test steps (one scenario)
TestStepSOAP Request, Properties, Property Transfer, Groovy Script, Delay, Conditional GotoOne action

Step 5: Add Assertions

Open a test step, click the Assertions tab at the bottom, then +:

AssertionChecksExample
SOAP ResponseResponse is a valid SOAP messageAlways add it
Not SOAP FaultNo Fault in the bodyPositive cases
SOAP FaultA Fault is presentNegative cases
Contains / Not ContainsText or regex in the response<AddResult>12</AddResult>; Not Contains “Exception”
XPath MatchValue at an XPath equals expectedSee below
Schema ComplianceResponse matches the WSDL/XSD typesContract check
Response SLAResponse time under N ms2000 ms
Valid HTTP Status CodesStatus is in a list200
Script AssertionCustom Groovy logicComplex rules

XPath Match assertion

Click Declare to let SoapUI add the namespaces, then write:

declare namespace soap='http://schemas.xmlsoap.org/soap/envelope/';
declare namespace ns1='http://tempuri.org/';
//ns1:AddResponse/ns1:AddResult

Expected result: 12. Namespace-free alternative that’s handy when prefixes change: //*[local-name()='AddResult'].

Why XPath beats “Contains” A Contains check for “12” also passes if the response says <ErrorCode>1203</ErrorCode>. XPath Match checks the value of the exact element, which is what a bank auditor would expect for an amount field.
Advertisement

Step 6: Negative Tests and SOAP Faults

Create a TestCase Divide - negative and send intA = 5, intB = 0. The real response:

HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=utf-8
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET

<soap:Fault>
  <faultcode>soap:Server</faultcode>
  <faultstring>System.Web.Services.Protocols.SoapException: Server was unable to process request.
    ---> System.OverflowException: Arithmetic operation resulted in an overflow.
    at Calculator.Divide(Int32 intA, Int32 intB) in G:\PleskVhosts\...\Calculator.asmx:line 19 ...</faultstring>
  <detail />
</soap:Fault>

Add assertions SOAP Fault and Valid HTTP Status Codes = 500. Then look closer, as a tester should. This demo service shows three issues you’d report in a real project:

  1. Information disclosure (security): the faultstring exposes a .NET stack trace, internal class names and the server’s file path. The X-AspNet-Version header reveals the framework version. (OWASP API8, Security Misconfiguration.)
  2. Wrong fault code: dividing by zero is a client input problem, so it should be soap:Client with a clear message such as “intB must not be 0”, not soap:Server.
  3. Misleading message: “overflow” instead of “division by zero”.

More negative cases to add: non-numeric input (abc, returns a fault), integer overflow (2147483647 + 1, also a fault), missing elements, empty body, wrong SOAPAction, wrong namespace, and malformed XML. Add a Not Contains assertion for “Exception” and “line” on every negative case to catch stack-trace leaks automatically.

Step 7: Properties: Stop Hardcoding Values

Define values once and reuse them with ${...} expansions:

  • Project property endpoint = http://www.dneonline.com/calculator.asmx, then set the request endpoint to ${#Project#endpoint}, so switching environments is one change.
  • TestCase property a = 20, b = 5, then the request uses <tem:intA>${#TestCase#a}</tem:intA>.
  • Expected values in XPath assertions can also use properties.

Passing values between steps (for example a session id from Login into GetBalance) uses Property Transfer, covered in the next lesson with REST examples: SoapUI REST and Data-Driven Testing.

Advertisement

Step 8: Run Suites and Read Results

  • Double-click the TestSuite and press the green Run button; each case turns green or red.
  • Open a failed step: the assertion panel shows exactly which assertion failed and why.
  • The TestCase Log shows timings per step; Raw tabs show the full HTTP exchange.

Command line and CI

# SoapUI ships testrunner.sh / testrunner.bat in its bin folder
./testrunner.sh -s"Calculator Regression" -r -j -f ./reports Calculator-soapui-project.xml
#  -s  test suite to run      -r  print summary report
#  -j  JUnit-style XML reports -f  output folder
#  -P endpoint=https://qa.bank.example/CoreBanking   override a project property

The whole project is one XML file (Calculator-soapui-project.xml), so keep it in Git and run it in Jenkins or GitHub Actions.

Testing SOAP Without SoapUI

SOAP is just XML over HTTP POST, so Postman (raw XML body + headers), cURL and Playwright can call it too. Playwright example from the same service:

import { test, expect } from '@playwright/test';

const URL = 'http://www.dneonline.com/calculator.asmx';
const envelope = (op: string, a: number | string, b: number | string) =>
  `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
     <soapenv:Body><tem:${op}><tem:intA>${a}</tem:intA><tem:intB>${b}</tem:intB></tem:${op}></soapenv:Body>
   </soapenv:Envelope>`;

async function call(request: any, op: string, a: number | string, b: number | string) {
  return request.post(URL, {
    headers: { 'Content-Type': 'text/xml; charset=utf-8', SOAPAction: `"http://tempuri.org/${op}"` },
    data: envelope(op, a, b),
  });
}

test('Multiply 6 x 7 = 42', async ({ request }) => {
  const res = await call(request, 'Multiply', 6, 7);
  expect(res.status()).toBe(200);
  expect(await res.text()).toMatch(/<MultiplyResult>42<\/MultiplyResult>/);
});

test('Divide by zero returns a SOAP Fault', async ({ request }) => {
  const res = await call(request, 'Divide', 5, 0);
  expect(res.status()).toBe(500);
  expect(await res.text()).toContain('<soap:Fault>');
});

Use SoapUI when the team relies on WSDL-driven work and non-coders; use code when SOAP tests must live alongside REST and UI tests in one framework.

Advertisement

SOAP Testing Checklist

  • WSDL loads; operations match the specification.
  • Every operation: valid input → correct values (XPath), Not SOAP Fault, schema compliant, within SLA.
  • Invalid input → SOAP Fault with correct faultcode (Client vs Server) and a useful message.
  • No stack traces, file paths or versions in faults or headers.
  • Both SOAP 1.1 and 1.2 bindings if both are published.
  • WS-Security: unsigned, expired or tampered messages are rejected.
  • XML attacks: XXE and very large or deeply nested XML are rejected.
Advertisement

Interview Questions: SoapUI and SOAP Testing

What is SoapUI?

An open-source tool for functional testing of SOAP and REST APIs. It creates requests from WSDL or OpenAPI definitions, supports assertions, properties, test suites, Groovy scripting, data-driven tests and command-line execution. ReadyAPI is the commercial version.

What is a WSDL?

An XML document describing a SOAP service: its operations, input and output messages, data types (XSD), bindings (SOAP 1.1/1.2) and endpoint address. SoapUI uses it to generate request templates.

What is the hierarchy of a SoapUI project?

Project, then TestSuite, then TestCase, then TestStep. The project also holds interfaces generated from WSDL/OpenAPI and properties at each level.

Which assertions do you use in SoapUI?

SOAP Response, Not SOAP Fault or SOAP Fault, Contains/Not Contains, XPath Match, XQuery Match, Schema Compliance, Response SLA, Valid HTTP Status Codes and Script Assertion for custom Groovy logic.

What is an XPath Match assertion?

It evaluates an XPath expression against the response (with declared namespaces) and compares the result with an expected value, for example //ns1:AddResult equals 12.

How are errors returned in SOAP?

As a SOAP Fault element inside the Body with faultcode, faultstring and optional detail, usually with HTTP status 500. SOAP 1.2 uses Code, Reason and Detail elements.

What is the difference between SOAP 1.1 and SOAP 1.2?

SOAP 1.1 uses Content-Type text/xml with a separate SOAPAction header and the schemas.xmlsoap.org envelope namespace. SOAP 1.2 uses application/soap+xml with the action as a parameter, the w3.org 2003/05 namespace, and a different fault structure.

How do you run SoapUI tests in CI?

With the testrunner command-line tool included with SoapUI, passing the project file, suite name and options for JUnit reports and property overrides. CI tools such as Jenkins then publish the reports.

What is the difference between SoapUI and ReadyAPI?

SoapUI Open Source is free and covers core functional testing. ReadyAPI is commercial and adds data-source steps without scripting, advanced reporting, service virtualisation, performance testing and team collaboration features.

What would you check in a SOAP Fault during testing?

The correct HTTP status, the fault code (Client for bad input, Server for server errors), a clear and safe message, no stack traces or internal paths, and the detail element if the contract defines error codes.

Advertisement
View the full API testing syllabus