If your Test Scenarios get increasingly complex, you might want to share a number of TestSteps between different TestCases, maybe for setting up some prerequisites (logging in, etc) or for performing certain steps in different contexts. As always, there are several ways to achieve this in soapUI;
By using a "Run TestCase" TestStep to execute other TestCases
By creating a Script TestStep and using the soapUI API to execute desired TestSteps, TestCases, etc.
Let's have a look at both of these in more detail
The "Run TestCase" TestStep
The Run TestCase TestStep presents a flexible approach to modularization; it executes the configured target TestCase optionally passing and retrieving properties before and after execution, for example you could use this to call a complex sequence of TestSteps to perform and validate a login procedure, passing the required credentials and receiving the resulting sessionid. When configuring the TestStep this would look something like the following:
The top two options are for selecting the actual target TestCase, the remaining options are related to property/session management and threaded execution. Lets have a look at these in detail;
The Run TestCase TestStep will contain the same properties as the selected target TestCase, allowing you to both specify values that will be passed to the target TestCase when it is executed (much like method arguments) and select properties as "Return Properties" whose values will be extracted from the target TestCase after it has executed (much like return values). Selecting the "Ignore Empty Properties" option will ensure that properties not containing any values in the calling TestStep will not overwrite any values in the target TestCase.
This calls for an example; let say we have set up the Run TestCase TestStep as above and now specify the following property values;
Now when running the Run TestCase TestStep (with the Run button in its toolbar), it copies the values of the username and password properties to the target TestCase and executes it. The target TestCase in turn performs a login and copies the resulting sessionid into the corresponding TestCase property, which in turn gets copied back to our calling TestStep;
You can view this as if we had called the Login TestCase as if it were a method taking input arguments and return others back to us.
Setting the Run Mode
When executing the target TestCase, the Run TestCase TestStep can be configured to do this in several different ways:
by creating an isolated copy of the target TestCase in memory and executing it. This has the advantage of supporting multiple simultaneous calls, for example if running the calling TestCase as a LoadTest. A drawback is that any property changes are lost after the TestCase has been executed, and that it requires more memory for the new copy to be executed.
by executing the existing TestCase; this is the straight-forward option that will work just fine as long as you don't need to call the same TestCase from several sources at the same time, in which case the calling Run TestCase Teststep will fail, unless you configure it to wait for the target TestCase to finish first (last option).
The above becomes especially relevant when running the TestCase containing the Run TestCase TestStep as a LoadTest; in this case the first option is the only one that will work smoothly, otherwise all threads in your LoadTest will be calling into the same instance of the TestCase which will either cause it to fail (second option above) or block execution of the LoadTest (third option).
Using Scripts for Modularization
As always the soapUI API allows you to accomplish this and much more via a script TestStep. The "Branching and Looping" document has already shown some examples on how to execute a single TestStep from within a script (with the testRunner.runTestStepByName method), lets have a quick look at how we could achieve the above scenario with a script instead;
// get TestCase
def tc = testRunner.testCase.testSuite.project.testSuites["Sample Simple TestSuite"]
.testCases["Simple Login and Logout w. Properties Steps"]
// set login properties
tc.setPropertyValue("Username", "ole" )
tc.setPropertyValue("Password", "nomoresecrets" )
// run test synchrouously
def runner = tc.run( null, false )
// show that it worked out ok
log.info "Status: $runner.status, time taken for TestCase was: $runner.timeTaken ms"
// assert that it didn't fail
assert runner.status != Status.FAILED : runner.reason
Here the target TestCase is retrieved and executed; if it fails an exception is thrown (via the assert statement) which will fail the Groovy Script TestStep also.