- SoapUI Cookbook
- Rupert Anderson
- 1031字
- 2021-07-23 20:19:20
Looping over CSV file data and driving tests with Groovy
Whether it is for loading test data or writing reports, using external data files can be a key part of automated testing. Typically, you might need to read test data from a file and loop over some test steps until there is no more data. In this recipe, we see how this can be achieved easily using several reusable Groovy TestSteps
.
Getting ready
For example, let's say we have a small CSV file of invoice data that we want to use to drive our tests:
1,comp1,100.0,2014-12-01 00:00:00 2,comp2,200.0,2014-12-02 00:00:00 3,comp3,300.0,2014-12-03 00:00:00
You can find this data in <chapter2 samples>/invoice.csv
.
We will read each line and extract the values into properties, for example, to do something useful, for example, populating a web service request.
I have provided a completed SoapUI project GroovyFiles-soapui-project.xml
in the Chapter2
samples.
How to do it...
I'm going to break this down into three separate Groovy TestSteps
: one to read the test data, another to extract it, and another to loop until all rows are processed. Perform the following steps:
- First, create
Groovy TestStep
calledLoadAllTestDataFromFile
and add the following code:context["rows"]=[] //Change this to the location of your CSV file. File testDataFile = new File("/temp/invoices.csv") testDataFile.eachLine {content, lineNumber -> context["rows"] << content } //Initialise row counter context["currentRowIndex"]=0 return "Loaded ${context["rows"].size()} rows."
There's no need to run this just yet. This step loads all the CSV rows into
List
and initializes a row counter variable. - Next, create a
Groovy TestStep
calledGetNextRowAndExractValues
:def currentRowIndex = context["currentRowIndex"] //Get values from csv row def rowItems = context["rows"][currentRowIndex].split(/,/) def invoiceId = rowItems[0] def invoiceCompany = rowItems[1] def invoiceAmount = rowItems[2] def invoiceDueDate = rowItems[3] //Increment counter context["currentRowIndex"] = currentRowIndex + 1 return "Row #$currentRowIndex processed."
- In this step, we extract all the fields with a view to doing something useful with the values and increment the row counter.
- Lastly, create a
Groovy TestStep
calledLoopIfMoreRows,
and add the following code:def currentRowIndex = context["currentRowIndex"] if (currentRowIndex < context["rows"].size) testRunner.gotoStepByName("GetNextRowAndExractValues")
- Now, run the
TestCase
that contains the threeGroovy TestSteps
, and you should see the following:Step 1 [LoadAllTestDataFromFile] OK: took 0 ms -> Script-result: Loaded 3 rows. Step 2 [GetNextRowAndExractValues] OK: took 0 ms -> Script-result: Row #0 processed. Step 3 [LoopIfMoreRows] OK: took 0 ms Step 4 [GetNextRowAndExractValues] OK: took 0 ms -> Script-result: Row #1 processed. Step 5 [LoopIfMoreRows] OK: took 0 ms Step 6 [GetNextRowAndExractValues] OK: took 0 ms -> Script-result: Row #2 processed. Step 7 [LoopIfMoreRows] OK: took 0 ms
This example doesn't actually use the test data, but this would be an easy next step for us.
How it works...
The first step exploits the Groovy File
class to read in the invoices.csv
file. The Groovy File
class is more convenient to use than the standard Java equivalent, and is imported automatically by Groovy. The eachLine
method allows us to append (using left shift <<
) each full line from the CSV file to a rows
collection that is stored in the SoapUI context.
Tip
SoapUI (TestCase) context variable
This holds the state or context
that is passed between TestSteps
. It is a good place to store properties that are required by subsequent TestSteps
. Properties added to the context
object are lost when the tests finish. In basic terms, the context
object is an implementation of java.util.Map
, but the actual implementation of the context
object is dependent on how you are running the TestStep
:
WsdlTestRunContext
is used when the TestStep
is run as part of a TestCase
.
MockTestRunContext
is used when you run a TestStep
individually.
SecurityTestRunContext
is used when the TestStep
is run as part of a security scan—see the Scanning web service security vulnerabilities recipe from Chapter 7, Testing Secured Web Services.
There is also a mock context
object of type WsdlMockRunContext
– see Chapter 3, Developing and Deploying Dynamic REST and SOAP Mocks
We also add currentRowIndex
to the context
object to keep track of the current row as we iterate through the TestSteps
for each row.
The GetNextRowAndExractValues
Groovy TestStep
extracts the current row from the context
and splits the row string by a comma to get an array of field values. Finally currentRowIndex
is then incremented and the text Row #$currentRowIndex processed
is returned just to provide some debugging output in the TestCase
window. It's inside the GetNextRowAndExractValues
Groovy
TestStep
that we could use the invoice CSV values (extracted to variables invoiceId
, invoiceCompany
, invoiceAmount
and invoiceDueDate
) to test something or alternatively pass them to another TestStep
, for example, use them to populate a web service request (see below example).
Lastly, the LoopIfMoreRows
TestStep
checks whether there are any rows left, and if so, uses the tesRunner.gotoStepByName()
method to repeat the GetNextRowAndExtractValues
TestStep
.
There's more...
Building on the previous example, the invoice CSV values could be used in a request for a test web service call. To do that, we would need to put the invoice values somewhere where we can accesses them from a subsequent REST Test Request TestStep
or (SOAP) Test Request TestStep
.
The context
object is a good place to set and get TestStep
properties and can be used to pass the 'state' between TestSteps
.
So, if we inserted the previous test steps around the last chapter's invoice CRUD service's POST REST Test Request TestStep
like the one shown in the following screenshot:

Then, we can add the following lines of Groovy just after extracting the values in GetNextRowAndExtractValues
:
//Create these context properties for use as parameters in the subsequent test steps context["invoiceCompany"]=invoiceCompany context["invoiceAmount"]=invoiceAmount
Then, we can access these context
properties using the ${property}
syntax in the request body of the POST REST Test Request TestStep
to create an invoice:
{"Invoice": { "companyName": "${invoiceCompany}", "amount": "${invoiceAmount}" }}
Tip
Context property scope
Unlike other SoapUI object properties for example project level properties, context
object properties do not require a #scope
qualifier when referenced directly using the Property Expansion
syntax as in the above example. For examples of how to reference other types of property in using the Property Expansion
syntax see http://www.soapui.org/scripting---properties/property-expansion.html.
Running these steps will then call the invoice CRUD service's POST method for each row of CSV invoice data. To see this working, start the service implementation (see the Generating SoapUI tests with REST discovery recipe of Chapter 1, Testing and Developing Web Service Stubs With SoapUI, for more info) and take a look at Invoice-CRUD-Project-soapui-project.xml
in the Chapter 2
samples.
If you need to work with JSON or XML file data, then take a look at the Groovy JSON and XML Slurpers (see the following links). They are easy to use and should take care of your parsing needs.
See also
- Custom Groovy data sources used in Chapter 9, Data-driven Load Testing With Custom Datasources
- For more information on Conditional Goto TestStep, visit http://www.soapui.org/Functional-Testing/conditional-goto.html
- For more information on Groovy JSON Slurper, go to http://groovy.codehaus.org/gapi/groovy/json/JsonSlurper.html
- For more information on Groovy XML Slurper, go to
- 深度實踐OpenStack:基于Python的OpenStack組件開發
- .NET之美:.NET關鍵技術深入解析
- LabVIEW2018中文版 虛擬儀器程序設計自學手冊
- Learning RxJava
- 高級C/C++編譯技術(典藏版)
- Nexus規模化Scrum框架
- Apache Mesos Essentials
- UML 基礎與 Rose 建模案例(第3版)
- GitHub入門與實踐
- Advanced UFT 12 for Test Engineers Cookbook
- Troubleshooting Citrix XenApp?
- Python預測之美:數據分析與算法實戰(雙色)
- 視窗軟件設計和開發自動化:可視化D++語言
- UML基礎與Rose建模實用教程(第三版)
- Using Yocto Project with BeagleBone Black