Functional Web Services Testing Made Easy with SoapUI - Part 2
Join the DZone community and get the full member experience.
Join For Free1. Format a date
The standard Java class for this task is SimpleDateFormat. This is a concrete subclass of DateFormat formats and parses dates and times using a string pattern, in our case, "yyyy-MM-dd". Let’s start by writing this in Java; later we will see how easily we can groovify this to use within SoapUI. Here is the Java code to get the date in the format “yyyy-MM-dd”.
java.util.Date today = new java.util.Date();
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
String todayStr = sdf.format(today);
We could leave the Groovy code exactly as it is above, but let’s make it groovier, removing the bells and whistles necessary in Java. Our code finally looks like this:
today = new Date()
sdf = new java.text.SimpleDateFormat("yyyy-MM-dd")
todayStr = sdf.format(today)
Not a lot of change, but considerably faster to type. The similarities to Java are just as we have said.
2. Reading and writing to a properties file
The java.util.Properties object does the work of reading and writing to a properties file in Java. This time we’ll go directly to the Groovy code:
sdf = new java.text.SimpleDateFormat("yyyy-MM-dd") todayStr = sdf.format(new Date()) props = new java.util.Properties () file = new File("C:/web-services-test/testprops.txt") if(!file.exists()) { file.createNewFile() props.today = todayStr props.zipCode = "20904" fos = new java.io.FileOutputStream ( file ) props.store(fos, "Writing the zipcode and today's date") }fis = new FileInputStream (file ) props.load (fis) today = props.getProperty ( "today" ) zipCode = props.getProperty ( "zipCode" )
Simple, right? Similarly, if you need to read from a database, you can do so in a few simple lines of Groovy code.
3.Parse XML
If you have been writing enterprise Java applications you have certainly needed to use XML, and you can testify that XML and Java is not easy. Parsing XML in Java requires a lot of boilerplate code and is really tedious.
You may remember from part 1 that I said I was lazy. Fortunately, Groovy comes to the rescue. We can parse XML in just 5 lines of code. Yes, that’s what I said, just 5 lines. Let’s see how to parse the response from the LatLonListZipCode web service from Part 1. The XML looks like this:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:LatLonListZipCodeResponse xmlns:ns1="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl">
<listLatLonOut xsi:type="xsd:string"><?xml version='1.0' ?>
<dwml version='1.0' xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.nws.noaa.gov/mdl/survey/pgb_survey/dev/DWMLgen/schema/DWML.xsd">
<latLonList>39.0138,-77.0242</latLonList>
</dwml></listLatLonOut>
</ns1:LatLonListZipCodeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The code to parse this in Groovy is so easy:
groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
holder = groovyUtils.getXmlHolder("LatLonListZipCode - Request 1#Response")
listLatLonOut = holder.getNodeValue( "//listLatLonOut" )
latlonNode = groovyUtils.getXmlHolder(listLatLonOut)
latlon = latlonNode.getNodeValue("//latLonList")
So much for preamble, let’s get to work. If you followed along with part 1 of this series, you should already have an NOAA-Weather-Service project. We’ll continue with the same web service here. In our earlier test case; we used today’s date and the latitude and longitude for Silver Spring. In the NDFDgenByDay Request, the startDate must be a String in the format “yyyy-MM-dd”. The NOAA web service has a function that returns us the latitude and longitude when provided with a ZIP code. This time we will read the data we require for this functional test from a properties file.
Let’s remind ourselves of the steps to creating the Test in SoapUI:
1.Create a New Test Suite and a Test case.
2.Within the Test Suite setup script, if the properties file does not exists, write to a new properties file today’s date and the default ZIP code.
3.Create a Properties object and assign the values read from the properties file to it.
4.Within the test case setup script, read from the properties file.
5.Use the zipCode property from the above step in the LatLonListZipCode request, which will return the latitude and longitude to us.
6.Use Groovy to assert that we retrieved the correct ZIP code and transfer the latitude and longitude down the line.
7.The NDFDgenByDayLatLonList request now uses the date from the property step 1, and the latitude and longitude from step 6.
8.Lastly, use Groovy step to parsing the XML, validate the response, and assert the results.
1. Create a New Test Suite and Test Case. Follow these steps:
a. Right click on the project, and select the New TestSuite menu item. Specify the name WeatherTestSuite.
b. Right click on the Test Suite you created above and select the New TestCase menu item. Specify the name WeatherTestCase.
2.Within the setup script for this test suite, we will write to the properties file using Groovy; formatted date and the zip code.
log.info("In the WeatherTestSuite Setup Script")
sdf = new java.text.SimpleDateFormat("yyyy-MM-dd")
todayStr = sdf.format(new Date())
props = new java.util.Properties ()
file = new File("C:/web-services-test/testprops.txt")
if(!file.exists())
{
file.createNewFile()
fis = new FileInputStream (file )
props.setProperty ( "today" , todayStr)
props.setProperty ( "zipCode" , "20904")
fos = new java.io.FileOutputStream ( file )
props.store(fos, "Writing the zipcode and today's date")
}
3. Add a Properties step.
Right click on the WeatherTestCase and select Add Step -> Properties. This opens up a new editor, within this editor create two new properties called, startDate and zipCode.
4.Within the setup script for the test case, we will read back from the properties file and assign the values to the properties step we added above. To recap:
log.info("In the WeatherTestCase Setup Script")
props = new java.util.Properties()
fis = new FileInputStream ("C:/web-services-test/testprops.txt")
props.load (fis)
today = props.getProperty ( "today" )
zipCode = props.getProperty ( "zipCode" )
targetStep = testRunner.testCase.getTestStepByName( "Properties" )
// transfer all properties
targetStep.setPropertyValue( "startDate", today)
targetStep.setPropertyValue( "zipCode", zipCode)
log.info(today)
log.info(zipCode)
5. Add the LatLonListZipCode - Request 1 to the test case with the zip code ${Properties#zipCode}. This retrieves the zip code from the properties step we defined above. The request XML is:
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ndf="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl">
<soapenv:Header/>
<soapenv:Body>
<ndf:LatLonListZipCode soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<zipCodeList xsi:type="dwml:zipCodeListType" xmlns:dwml="http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd">${Properties#zipCode}</zipCodeList>
</ndf:LatLonListZipCode>
</soapenv:Body>
</soapenv:Envelope>
6.Parse the response from the above request using Groovy and assert.
Right click on the Test Case and select the Add Step -> Groovy Script. This will open up an editor. In this editor, we will write the Groovy script that will parse the response and also add a few assertions. Also, assign the latitude and longitude to the context which can be used within the next request.
groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
holder = groovyUtils.getXmlHolder("LatLonListZipCode - Request 1#Response" )
listLatLonOut = holder.getNodeValue( "//listLatLonOut" )
assert listLatLonOut != null
assert listLatLonOut.length() > 0
latlonNode = groovyUtils.getXmlHolder(listLatLonOut)
latlon = latlonNode.getNodeValue("//latLonList")
log.info(latlon)
assert latlon !=null
context["latlon"] = latlon
7.Add the NDFDgenByDayLatLonList - Request 1 to the test case.
In this request, we are going to retrieve the date as well as the latitude and longitude from the context.
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ndf="http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl">
<soapenv:Header/>
<soapenv:Body>
<ndf:NDFDgenByDayLatLonList soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<listLatLon xsi:type="dwml:listLatLonType" xmlns:dwml="http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd">${latlon}</listLatLon>
<startDate xsi:type="xsd:date">${Properties#startDate}</startDate>
<numDays xsi:type="xsd:integer">1</numDays>
<format xsi:type="dwml:formatType" xmlns:dwml="http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd">12 hourly</format>
</ndf:NDFDgenByDayLatLonList>
</soapenv:Body>
</soapenv:Envelope>
8.Finally, let’s create another Groovy step that parses the response and add a few assert statements.
groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
holder = groovyUtils.getXmlHolder("NDFDgenByDayLatLonList - Request 1#Response" )
dwmlByDayOut = holder.getNodeValue( "//dwmlByDayOut" )
//log.info(dwmlByDayOut)
assert dwmlByDayOut.length() > 298
dwml = groovyUtils.getXmlHolder(dwmlByDayOut)
headTitle = dwml.getNodeValue("//head/product/title")
headField = dwml.getNodeValue("//head/product/field")
//log.info(headTitle)
//log.info(headField)
assert "NOAA's National Weather Service Forecast by 12 Hour Period".equals(headTitle)
assert "meteorological".equals(headField)
Now run it and see lots of green!
You can also right click on the WeatherTestSuite and select the menu item Launch TestRunner, which opens up a dialog as such:
Click the Launch button, and you should be able to see the results in another window:
Running soapUI TestRunner for [Weather]
directory: C:\Program Files\eviware\soapUI-2.0.2\bin\.
command: cmd.exe /C testrunner.bat -sWeatherTestSuite -cWeatherTestCase -r -a -j -f C:\web-services-test C:\Documents and Settings\msubbarao\Desktop\Weather-soapui-project-part2.xml
soapUI 2.0.2 TestCase Runner
Configuring log4j from [jar:file:/C:/Program%20Files/eviware/soapUI-2.0.2/bin/soapui-2.0.2.jar!/soapui-log4j.xml]
18:32:30,692 INFO [DefaultSoapUICore] initialized soapui-settings from [C:\Program Files\eviware\soapUI-2.0.2\bin\soapui-settings.xml]
18:32:31,723 INFO [WsdlProject] Loaded project from [file:/C:/Documents%20and%20Settings/msubbarao/Desktop/Weather-soapui-project-part2.xml]
18:32:32,494 INFO [SoapUITestCaseRunner] Running soapUI tests in project [Weather]
18:32:32,504 INFO [SoapUITestCaseRunner] Running soapUI suite [WeatherTestSuite], runType = SEQUENTIAL
18:32:33,015 INFO [log] In the WeatherTestSuite Setup Script
18:32:33,125 INFO [log] In the WeatherTestCase Setup Script
18:32:33,165 INFO [log] 2008-05-11
18:32:33,175 INFO [log] 20904
18:32:33,175 INFO [SoapUITestCaseRunner] Running soapUI testcase [WeatherTestCase]
18:32:33,336 INFO [SoapUITestCaseRunner] running step [Properties]
18:32:33,376 INFO [SoapUITestCaseRunner] running step [LatLonListZipCode - Request 1]
18:32:34,577 INFO [HttpClientSupport$Helper] Initializing SSL
18:32:35,008 WARN [AbstractSoapVersion] Ignoring validation error: error: cvc-complex-type.3.2.2: Attribute not allowed: encodingStyle@http://schemas.xmlsoap.org/soap/envelope/ in element Envelope@http://schemas.xmlsoap.org/soap/envelope/
18:32:35,008 INFO [SoapUITestCaseRunner] Assertion [SOAP Response] has status VALID
18:32:35,048 INFO [SoapUITestCaseRunner] running step [AssertLatLon]
18:32:35,719 INFO [SoapUITestCaseRunner] running step [NDFDgenByDayLatLonList - Request 1]
18:32:35,909 WARN [AbstractSoapVersion] Ignoring validation error: error: cvc-complex-type.3.2.2: Attribute not allowed: encodingStyle@http://schemas.xmlsoap.org/soap/envelope/ in element Envelope@http://schemas.xmlsoap.org/soap/envelope/
18:32:35,909 INFO [SoapUITestCaseRunner] Assertion [SOAP Response] has status VALID
18:32:35,969 INFO [SoapUITestCaseRunner] running step [AssertWeatherResponse]
18:32:36,049 INFO [SoapUITestCaseRunner] Finished running soapUI testcase [WeatherTestCase], time taken: 1097ms, status: FINISHED
18:32:36,110 INFO [log] In the WeatherTestCase TearDown Script
18:32:36,120 INFO [log] In the WeatherTestSuite TearDown Script
18:32:36,120 INFO [SoapUITestCaseRunner] soapUI suite [WeatherTestSuite] finished in 3616ms
SoapUI 2.0.2 TestCaseRunner Summary
-----------------------------
Time Taken: 3621ms
Total TestSuites: 1
Total TestCases: 1 (0 failed)
Total TestSteps: 5
Total Request Assertions: 2
Total Failed Assertions: 0
Total Exported Results: 5
We saw in this article how to use Groovy with SoapUI to create properties, transfer properties to requests, and to validate responses and assert expected results. If you know Java, writing Groovy scripts is a piece of cake. You can run these scripts from within the UI, as we saw. Of course, we have only covered a small fraction of what we actually do in any enterprise application. Once we know how to use Groovy, the entire Java API is available to you for easy use within SoapUI.
The next part of this series covers integrating tests with your build tool, running these tests as part of your builds, and creating JUnit reports.
Stay tuned.
Additional Resources:
1. SoapUI
2. Groovy
3. Java 6 API
Opinions expressed by DZone contributors are their own.
Comments