Working with Lists in Groovy
def myList = ["One", "Two", "Three", "Four"]
This creates a list of four strings. Note the use of brackets ([ and ]) to enclose the items in the list; each item is also separated by a comma. You can retrieve individual items in the list like this:
myList[0]
This would return the first item in the list-- "One" in this case. The format is listName[x], where x is the zero-based position, or index, of the item in the list. By zero-based, I mean we start counting at zero when determining an item's index: the first item in the list is at index 0, the second is at index 1, the third is at index 2, etc.
Since lists are objects, they have their own methods; here's some code illustrating a few of them:
def myList = ["One", "Two", "Three", "Four"] log.info("List contents: $myList") //size()-- returns number of items in the list log.info("Size is " + myList.size()) log.info("Element one is " + myList[0]) //indexOf()-- returns the index of a given item in the list log.info("Index of 'Four' is " + myList.indexOf("Four")) //add()-- adds an item to the list myList.add("Five") log.info("After adding 'Five', size is " + myList.size()) log.info("Element five is " + myList[4]) //remove()-- removes an item from the list myList.remove("Two") log.info("After removing 'Two', size is " + myList.size()) log.info("List contents now: $myList")
The output from this script:
A SoapUI Project Using Lists
The SetZipList Groovy Script step establishes a list of zip codes to use with the HTTP requests and sets it as a context property (note that using a list here is done for illustrative purposes; in truth it would probably be more practical to just hard code the zip codes in each test step):
context.zipList = ["19106","20500","10118","57751"]
The members of the list are plugged into each HTTP request using a special form of property expansion. Here's a screenshot of the first HTTP request step:
Note the value for the ZipCode parameter of our request-- this is a property expansion expression incorporating Groovy Script. The "$" and enclosing braces are standard property expansion syntax; however, the "=" signifies that what follows within the braces is Groovy Script.
context.zipList[0]
returns the first item in the list we created in the first test step ("19106"), using it as our ZipCode parameter in the request. Each HTTP request step is set up the same way, with each retrieving a different item in the list (the second request gets the second item, the third the third item, etc.).The following script is in the test case tear down:
def resultsList = testRunner.getResults() for(res in resultsList){ if(res.getTestStep().getClass() == com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequestStep){ def tStep = res.getTestStep() log.info(" Step Name = " + tStep.getName()) log.info(" URL = " + res.getProperty("URL")) log.info(" Status = $res.status") log.info(" Time Taken = $res.timeTaken ms") } }
This script retrieves select information from our test results and writes them to the log. The first line uses the getResults() method of the test case's built-in testRunner object to retrieve the results of the test case's test steps, returned in a list.
Using for and if
for (varName in list) {
Set of actions to perform...
}
This takes each item in list list and assigns it to the variable varName, then performs the actions contained in the braces ({ and }). The code is repeated for every item in the list. So in our script above, the first result in resultsList is assigned to variable res and the code in the brackets is executed. If there's another item in the list, that item then gets assigned to res and the code in the brackets is repeated, and so on, until all the items in the list have been processed.
You should recognize most of the code within the brackets as method calls, but the line starting with if may be unfamiliar. There's a problem in our for loop-- it iterates over every item in our list of results, including results from the first test step, the Groovy Script test step. Consequently, not all of the method calls we attempt to make are valid-- the getProperty() call, for example, would fail when we tried to call it on the results from the first test step.
The if statement allows us to run or not run code based on certain criteria. The basic syntax for the if statement:
if (test expression that evaluates to true or false){
Code to execute if test expression is true
}[else{
Code to execute if test expression is false
}]
The else clause is optional, and in fact there's no else clause used in our example. The if statement there checks to see if our results were generated by an HTTP test request step-- if they were (the expression evaluates to true), then the code in the brackets is safe to execute; if they weren't, the code in the brackets is skipped. Note the operator used to check for equality-- == and not = as you might expect. Other basic comparison operators include > (greater than), < (less than), >= (greater than or equal to), <= (less than or equal to), and != (not equal to).
Also note the indentation used in the script; with each block an extra level of indentation is used. While not strictly required, this is considered good practice for readability-- you can easily see where the for block and if block begin and end.
Finally, here's the output in the script log produced by the tear down script: