SoapUI REST Testing, Property Transfer and Data-Driven Tests
SoapUI isn’t only for SOAP. Many enterprise QA teams use one SoapUI project for both their legacy SOAP services and their newer REST APIs. In this lesson you’ll build a REST project against the live SQA Tools practice API, assert JSON with JSONPath, pass a login token between steps with Property Transfer, write small Groovy scripts and run a data-driven test from a CSV file, all with the free open-source edition.
$.access_token → a TestCase property used as Bearer ${#TestCase#token}). For data-driven testing in the open-source edition, read a CSV in a Groovy Script step and loop the request; ReadyAPI offers DataSource and DataSource Loop steps without code.Create a REST Project
- File → New REST Project.
- URI:
https://sqatools.in/wp-json/sqa-api/v1/users/1and click OK. - SoapUI splits it into a service (endpoint
https://sqatools.in), a resource (/wp-json/sqa-api/v1/users/1), a method (GET) and a request. - Click the green arrow. Switch the response view to JSON; check Raw for status and headers.
Alternatively, Import an OpenAPI/Swagger file (File → Import Swagger/OpenAPI, or via the plugin in some versions) to create every resource at once.
https://sqatools.in/wp-json/sqa-api/v1/users/1curl -i \
"https://sqatools.in/wp-json/sqa-api/v1/users/1"Better structure with parameters
Edit the resource path to /wp-json/sqa-api/v1/users/{id}. SoapUI adds a TEMPLATE parameter id. Add QUERY parameters such as role, page, per_page on a /users resource. Parameter styles: QUERY, TEMPLATE (path), HEADER, MATRIX, PLAIN.
Create a TestSuite for the REST API
| TestCase | Steps |
|---|---|
| Users – read | GET user 1, GET user 999, GET user abc |
| Users – pagination | GET page 2 per_page 5, GET per_page 51 |
| Objects – CRUD | POST, GET, PATCH, DELETE, GET (404) |
| Auth – token flow | POST login, Property Transfer, GET /auth/me |
| Validation – data driven | Groovy loop over CSV + POST /validate/user |
Right-click a request → Add to TestCase, as you did for SOAP.
JSON Assertions in SoapUI
| Assertion | Example | Expected |
|---|---|---|
| Valid HTTP Status Codes | – | 200 |
| JsonPath Match | $.data.name | Asha Verma |
| JsonPath Existence Match | $.data.email | true |
| JsonPath Count | $.data (on page 2) | 5 |
| JsonPath RegEx Match | $.data.email | .+@.+\..+ |
| Contains | – | "role":"admin" |
| Response SLA | – | 2000 ms |
| Script Assertion | Groovy logic | See below |
For older SoapUI versions without JsonPath assertions, SoapUI also exposes JSON responses as XML, so XPath Match works on them too (e.g. //data/name).
Script Assertion (Groovy) for business rules
import groovy.json.JsonSlurper
def json = new JsonSlurper().parseText(messageExchange.responseContent)
def order = json.data
order.items.each { item ->
assert item.line_total == item.quantity * item.unit_price
}
def subtotal = order.items.sum { it.line_total }
assert order.summary.subtotal == subtotal
assert Math.abs(order.summary.total - (subtotal * 1.18)) < 0.01
assert messageExchange.timeTaken < 2000
Attach it to a GET /orders/5001 step: it proves the totals are internally consistent, which no simple Contains check can.
Property Transfer: Chain Login → Protected Call
- Step 1, REST Request “Login”:
POST /wp-json/sqa-api/v1/auth/login, media typeapplication/json, body:{ "username": "${#Project#username}", "password": "${#Project#password}" } - Add TestCase property
token(empty). - Step 2, Property Transfer: Source = Login, Property = Response, path language JSONPath, path
$.access_token. Target = TestCase, Property = token. - Step 3, REST Request “Me”:
GET /wp-json/sqa-api/v1/auth/me, add headerAuthorization=Bearer ${#TestCase#token}. - Assert on Step 3: status 200, JsonPath
$.data.role=admin.
Set project properties username = admin and password = admin@123 (these are public practice credentials). For real systems, pass passwords at run time with -P on the command line instead of saving them in the project file.
Property expansion syntax
| Syntax | Reads from |
|---|---|
${#Project#name} | Project property |
${#TestSuite#name} | TestSuite property |
${#TestCase#name} | TestCase property |
${StepName#Response#$.path} | Directly from an earlier step’s response (JSONPath/XPath) |
${#Global#name}, ${#Env#VAR} | Global property / OS environment variable |
${=new Date().time} | Inline Groovy expression |
Groovy Script Steps: Small Code, Big Wins
A Groovy Script test step can generate data, read files, call other steps and log. Some everyday snippets:
// Unique test data
def uid = UUID.randomUUID().toString().take(8)
testRunner.testCase.setPropertyValue("objectName", "soapui-" + uid)
// Read a property and log it
def token = testRunner.testCase.getPropertyValue("token")
log.info "Token starts with: " + token?.take(12)
// Read the previous step's JSON response
def resp = context.expand('${Create Object#Response}')
def id = new groovy.json.JsonSlurper().parseText(resp).id
testRunner.testCase.setPropertyValue("objectId", id)
// Run another step by name
testRunner.runTestStepByName("Delete Object")
Data-Driven Testing from a CSV (Open Source)
Goal: test the age boundaries of POST /validate/user (18 to 100) from a file.
age,expected
17,422
18,200
100,200
101,422
TestCase “Validation – data driven” with three steps:
- Validate (REST Request, disabled so it runs only when called):
POST /wp-json/sqa-api/v1/validate/userwith body{ "name": "Asha", "email": "asha@example.com", "age": ${#TestCase#age} } - Loop (Groovy Script):
def rows = new File(context.expand('${#Project#dataDir}') + "/ages.csv").readLines().drop(1) def failures = [] rows.each { line -> def (age, expected) = line.split(",")*.trim() testRunner.testCase.setPropertyValue("age", age) def result = testRunner.runTestStepByName("Validate") def status = result.messageExchange.responseStatusCode log.info "age=${age} -> ${status} (expected ${expected})" if (status != (expected as int)) failures << "age ${age}: got ${status}, expected ${expected}" } assert failures.isEmpty() : failures.join("\n")
The script fails the TestCase with a clear list of mismatches. Add more columns (name length, email format) to cover other fields.
https://sqatools.in/wp-json/sqa-api/v1/validate/usercurl -i \
-X POST \
-H "Content-Type: application/json" \
-d '{"name":"Asha","email":"asha@example.com","age":101}' \
"https://sqatools.in/wp-json/sqa-api/v1/validate/user"Environments and Endpoints
- Use a project property for the host (
${#Project#host}) in the service endpoint. - Override at run time:
testrunner.sh -Phost=https://qa.example.com .... - ReadyAPI adds an Environments switcher similar to Postman’s.
Common SoapUI Problems and Fixes
| Problem | Fix |
|---|---|
| 415 Unsupported Media Type on POST | Set the request Media Type to application/json |
Property shows as literal ${...} | Check spelling and scope (#Project vs #TestCase); property names are case-sensitive |
| JsonPath returns nothing | Test the path in the Outline tab; JSON root is $ |
| SSL errors on test servers | Import the certificate into SoapUI’s JRE keystore; avoid disabling checks globally |
| Project file merge conflicts in Git | Enable “Composite project” so each test is a separate file |
| Slow or flaky public service | Add a Delay step or retries; increase socket timeout in Preferences |
Running REST Suites in CI
./testrunner.sh \
-s"SQA Practice REST" \
-PbaseHost=https://sqatools.in \
-Ppassword="$QA_PASSWORD" \
-r -j -f ./reports \
SQA-Practice-soapui-project.xml
Publish reports/*.xml with your CI’s JUnit report step. A failing assertion returns a non-zero exit code and fails the build.
SoapUI vs Postman vs Playwright for REST
| SoapUI | Postman | Playwright | |
|---|---|---|---|
| SOAP support | Excellent (WSDL-driven) | Basic (raw XML) | Manual (raw XML) |
| REST support | Good | Excellent | Excellent |
| Scripting language | Groovy | JavaScript | TypeScript |
| Data-driven | Groovy (free) / DataSource (paid) | CSV/JSON in Runner/Newman | Native loops and fixtures |
| Best fit | Enterprise SOAP + REST teams | Exploration, mixed-skill teams | Engineering-led automation, UI + API |
Interview Questions: SoapUI REST and Data-Driven Testing
Can SoapUI test REST APIs?
Yes. Create a REST project from a URI or an OpenAPI definition, define resources, methods and parameters, and use JSON-aware assertions such as JsonPath Match together with status code, SLA and script assertions.
What is Property Transfer in SoapUI?
A test step that copies a value from one place to another, for example extracting $.access_token from a login response with JSONPath and storing it in a TestCase property used by later requests.
What are the property levels in SoapUI?
Global, Project, TestSuite, TestCase and TestStep properties, plus environment variables. They are referenced with property expansion syntax such as ${#Project#name} or ${#TestCase#name}.
How do you do data-driven testing in SoapUI open source?
Read data from a CSV, Excel or database in a Groovy Script step, set TestCase properties for each row and run the request step by name in a loop, asserting results per row. ReadyAPI provides DataSource and DataSource Loop steps without code.
What are TEMPLATE and QUERY parameters in SoapUI REST?
TEMPLATE parameters are path parameters inside the resource path, like {id} in /users/{id}. QUERY parameters are appended after the question mark, like ?role=admin.
What is Groovy used for in SoapUI?
Script steps and script assertions: generating data, parsing responses, complex validations, controlling test flow, reading files and databases, and logging.
How do you override environment values when running SoapUI from the command line?
Use testrunner with -P options to override project properties, for example -Phost=https://qa.example.com, and keep endpoints and credentials as properties in the project.
How do you validate JSON values in SoapUI?
With JsonPath Match, JsonPath Existence, JsonPath Count and JsonPath RegEx assertions, or with a Groovy Script Assertion using JsonSlurper for complex rules.
What is a composite project in SoapUI?
A project saved as a folder of files instead of one large XML, which reduces merge conflicts when several testers work in the same project under version control.
Why would a team use SoapUI instead of Postman for REST?
When the team already uses SoapUI for SOAP services and wants one tool, project and CI runner for both, or prefers Groovy scripting and SoapUI’s assertion model.