Beginning soapUI Scripting 4: Lists, for, and if

Many of the methods you'll encounter in soapUI return lists, objects that can contain multiple data items.  In this post we'll cover some of the techniques and methods for working with lists, the for statement-- which is frequently used with lists, and the if statement, used for basic control flow.  For this post we'll actually use these concepts (and some of the others previously covered) with HTTP test requests, illustrating their practical application in soapUI.

Working with Lists in Groovy

In Groovy, you can create a list using the following syntax:

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

Now let's take a look at our example project; you can download a zipped version of it here. Download it, unzip it, and import it into soapUI.  The test suite consists of a single test case with four HTTP test requests; the service we're testing takes a zip code and returns the U.S. state where the zip code is located.

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

Frequently when dealing with a list, you'll want to iterate through it and perform some action or set of actions on each individual item.  A for statement is one way to do this.  The basic syntax:

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:

No comments:

Post a Comment

Please be respectful of others (myself included!) when posting comments. Unfortunately, I may not be able to address (or even read) all comments immediately, and I reserve the right to remove comments periodically to keep clutter to a minimum ("clean" posts that aren't disrespectful or off-topic should stay on the site for at least 30 days to give others a chance to read them). If you're looking for a solution to a particular issue, you're free to post your question here, but you may have better luck posting your question on the main forum belonging to your tool's home site (links to these are available on the navigation bar on the right).