soapUI Tips n Tricks – Part 2

This post is a follow up on my earlier post – soapUI Tips n Tricks – Part 1. I hope my readers find this post as much of use as the previous one. In this part, I shall try to cover simple but little more involved soapUI tricks. Once again please note that tips n tricks covered in this post may or may not apply to you as soapUI keeps evolving with its newer releases. Nevertheless, its useful to have a list of nuances and workarounds to those handy as you may find those useful for a given version of soapUI.

  1. Composite Projects in soapUI: soapUI by default, stores the project in one xml file. You can open this project file in soapUI by importing it. You can even edit this xml file in any simple editor, if you know what exactly you want to edit “in bulk” at times. soapUI, however, introduced concept of “composite project” in version 2.5. You can turn ON composite project by selecting “true” option in front of “Composite Project” property under your project’s properties listed on left hand bottom pane when you open your project. The default value for this property is set to “false”. Once you set this property to “true”, soapUI starts saving this project under a directory – as a composition of multiple directories – one each for each binding, each TestSuite. Each test-case is then stored under each TestSuite directory as an independent xml file. This is useful when you have multiple people working on different test-cases in a single project. So one person does not run over changes made by the other assuming the two are working on two different TestSuites OR two different test-cases. On caveat with using composite projects is when you use this feature with version control systems. When you change names of your test-cases the version control system is not aware of this name changes, hence you land up having multiple version of same file when you do next “update” in your version control system like cvs or svn. Then you shall have more headaches maintaining multiple versions of files and deleting old ones and do this as an extra step as opposed to soapUI + version control take care of it for you.

  2. Using soapUI code-templates on Mac: soapUI introduced another new feature in version 2.5 Pro and that was code-templates. If you open up soapUI preferences, you shall find a tab “Code Templates”. In here you shall find that you can define a block of code for a given string. For example, you can provide a string “savefile” and perhaps have 10 lines of code that represents this repetitive task of saving to a file. Later in your groovy script you can enter word “savefile” and press CTRL+SPACE and that auto completes this word into the block of code you defined in your code templates preferences. In fact this is documented on soapUI website. What they don’t tell you is this does not work as expected on Macs. On Macs you have to use SHIFT+SPACE instead of CTRL+SPACE to achieve the same!

  3. Using dates in dynamic property expansion: soapUI 2.5 has very useful feature – dynamic property expansion. Again this is reasonably documented on soapUI website. I found this incredibly useful when dealing with web services that are time sensitive and your test cases always need to have dates that are say “5 days from now”. As your test-case grows older it starts failing as it refers to the hard coded dates. This is where you can make use of dynamic properties right within your SOAP Request step or even provide it in properties for TestSuite, Project or TestCase and then substitute this property in your SOAP Request step. Here is an example:
    ...
    ...
     <!-- text within dateEffectiveFrom tag is replaced with a date 10 days from today in yyyy-MM-dd format -->
     <dateEffectiveFrom>${=  String.format('%tF', new Date() + 10) }</dateEffectiveFrom>
    
    <!-- TestSuite property "date" is defined as "${=  String.format('%tF', new Date() + 10) }" -->
    <!-- Another example where dynamic date is defined as TestSuite property -->
    <!-- and then SOAP Request can refer to this TestSuite property as shown below -->
     <dateEffectiveFrom>${#TestSuite#date}</dateEffectiveFrom>
    ...
    ...
    
  4. Running TestSuite cases in parallel: For a long time I kept using the default soapUI behavior that runs all test-cases in a given test suite in succession one after the other. I realized that soapUI provides an option to run these test-cases in parallel as well. This is very useful if you have a number of test-cases in your testsuite and you want to save time by running them in parallel as opposed to waiting for one test-case to complete to execute another, of course, assuming that the sequence execution of test-cases does not matter. Image below shows the default (third from left) option selected where tests run in serial fashion. If you select the (fourth option from left) option that shows arrows in parallel, this makes your tests run in parallel when you hit green “play” button to execute the test suite.
    Test-Cases in Parallel
  5. Disabling TestSuite, TestCase or a test step: I find this feature very handy especially when I am working with a number of test-cases at a time and want to put one test-case on hold and come back to it later. If you right click on TestSuite, TestCase or Test Step in soapUI, you shall notice an option in pull down menu called “Disable TestSuite” or “Disable TestCase” or “Disable Test Step” as the case may be. If you select this option the corresponding test suite, test case or test step shows up in grey color. So next time you run the project, test suite or a test case the corresponding disabled test suite, test case or a test step is not executed as a part of that run.

  6. Datasource Options: Do take advantage of Datasource options provided when using ‘Datasource’ step in soapUI. Let’s refer to the datasource options available in soapUI Pro:
    Datasource Options in soapUI
    Pay attention to “Start Row and End Row” options shown above. These are very handy when you want to test your code for just a few rows initially. If you don’t set these to any value, datasource shall process all the records in your data source. Using “trim data values” is also a handy option when dealing with string values. I find “go to loop” very handy as well as this takes care of any empty rows especially say when you have a given excel file with hundreds of records and many rows are empty at random. This way you don’t have to worry about empty rows in your groovy code.

  7. Be careful using testRunner.gotoStepByName in your groovy script: This may not be obvious to you the first time you use this method on testRunner. Logically, if you use this code in the middle of the script you would think that the execution of this script would stop and move to the next step defined in the call. But that is not what happens in reality. When you execute this call in a groovy script step, the entire groovy script step has to finish first and then only the flow of control moves to the step given in the call ‘gotoStepByName’. This is because this call is invoked on testRunner and for testRunner ‘test step’ being executed is the smallest unit of work and that needs to complete before test runner executes next direction given by the call ‘gotoStepByName’. Hope this clears your confusion if you had any regarding this call on testRunner.

  8. My SOAP Request steps uses dynamic property expansion but I want to capture actual xml with data: If your SOAP Request step uses dynamic property expansion by substituing actual data in xml using TestSuite properties or test case properties your request would have heavy use of expressions like ${#TestSuite#property1}. When you execute this test-case or testsuite, soapUI retains these expressions. In other words when you double click on fresh SOAP Request step just executed (that shows in green assuming it succeeded) you shall see the expressions and not the actual data. In many cases you might want to capture the actual xml data being sent. What you do is follow the soapUI log from soapUI log tab at the bottom. The log shows steps being executed one after the other. Once you see the step you are interested in the log, double click on it and that opens up this SOAP Request step in SOAP Message viewer where you can see request and response xmls in a message viewer. You can simply format this xml and copy paste in order to capture your data within xml.

  9. Make sure you check off “Use XQuery” when using X Query in property transfers: In one of my earlier posts on Property Transfers using XPath and XQuery, I had explained how to use XQuery expression in property transfers in soapUI. Figure below shows the XQuery I used in my example in that post. Do remember to check off “Use XQuery” option as shown in the figure. This is a common mistake made and you would probably not even realize the mistake even though “Use XQuery” option is in right front of you.
    Proprty Transfers using XQuery in soapUI

  10. Using paths relative to project directory: soapUI project has a property ‘Resource Root’. Be default its blank. But you can select ${projectDir} as its value from the drop down given. You shall find this property in project’s properties under left hand side bottom pane. If you select ${projectDir} as your resource root all paths are resolved with respect to your project directory or project file.

I hope you found this post of some use. I guess I shall stop here until I come back with part 3.

~srs

Spring web service call using proxy per connection

Very often we work behind a firewall and have a proxy server that we route our outgoing requests through. Sometimes we even need to use proxy server in order for the target web service to identify the request sender. In such cases, we need to set a proxy host and a proxy port that all our requests would be sent via. Details on how to set proxy are not so publicly documented in java documentation. However, some googling shalll tell you that you can set the proxy host and port by setting System.properties in jvm as shown below:

            Properties sysProps = System.getProperties();
            sysProps.put("proxySet", "true");
            sysProps.put("proxyHost", "192.168.1.111");
            sysProps.put("proxyPort", "8080");

The example above sets “proxySet” property to true and then sets “proxyHost” and “proxyPort” to the proxy server ip address and the port. You can even define these properties in your spring context and pass them to your class’s init-method that you can again define in spring context. This way you can achieve setting of proxy via spring context. What this does is sets the proxy on JVM. There are times when you would wonder how do I set this just per connection so that it doesn’t affect any other code running in JVM? That is exactly what I shall try to cover in this post.

Some time ago, I wrote a post on how to set socket timeout in spring using http client. To recap, all we did in that exercise was following:

  1. Declare http client dependency in maven pom.
  2. In Spring context, define your custom HttpClientParams by setting soTimeout property on it.
  3. In Spring context, define your custom HttpClient by injecting your custom HttpClientParams onto it.
  4. In Spring context, define your custom CommonsHttpMessageSender by injecting the HttpClient you just defined in the step before.
  5. In Spring context, define reference to your custom “CommonsHttpMessageSender” in a list of messageSenders that Spring WebServiceGatewaySupport accepts.

Now, we shall follow a similar pattern and try to set proxy per connection right within spring context. For simplicity, I am covering a case of simple proxy without the need of username and password i.e. just with host and port. We shall use the same HttpClient class and set a HostConfiguration on it, so in java you can do following:


import org.apache.commons.httpclient.HostConfiguration;
...
...
//Say, in your code you have handle "httpClient" - your HttpClient 

HostConfiguration myHostConfig = new HostConfiguration();
//Setting proxy server host and port onto host config
myHostConfig.setProxy("192.168.1.111",8080)
//Setting hostconfig onto http client
httpClient.setHostConfiguration(myHostConfig);
...
...

The example above shows how you could set HostConfiguration onto your HttpClient in order to achieve setting of proxy host and port onto your connection only. But this is all in java code and remember we want to achieve our goal right within spring context ! The problem in doing this in spring context is that HostConfiguration class does not provide us with any javabean compliant methods / property in order to set proxy host and port. And because of this we cannot directly use HostConfiguration class as a bean in spring context. To understand this further, please refer to HttpClient 3.1 javadocs. The version of HttpClient we are using (HttpClient 3.1), the HostConfiguration has following methods for setting and getting proxy host and port:

void setProxy(String proxyHost, int proxyPort);
void setProxyHost(ProxyHost proxyHost);
String getProxyHost();
int getProxyPort();

So if you notice above, the setProxyHost takes ProxyHost type as an argument and getProxyHost actually returns a String type. We could have used setProxyHost and getProxyHost methods in order to set our proxy settings within spring context onto our HostConfiguration but since these get-set methods do not comply by javabean contract of setting and getting the same type, spring would complain if you try to use this get-set approach in order to set your proxy onto HostConfiguration bean in spring context. What we can do is a little trick: extend the HostConfiguration class and create our own MyHostConfiguration class as shown below:

package mypackage;

import org.apache.commons.httpclient.HostConfiguration;

public class MyHostConfiguration extends HostConfiguration {

    private final String DELIMITER = ":";

    public synchronized String getProxyHostPlusPort() {
        
        return new StringBuffer(getProxyHost()).append(DELIMITER).append(getProxyPort()).toString();
    }

    public synchronized void setProxyHostPlusPort(String proxyHostPlusPort) {

        if (null == proxyHostPlusPort)
            throw new IllegalArgumentException("proxyHostPlusPort string cannot be null");
        if (proxyHostPlusPort.indexOf(DELIMITER) == -1)
            throw new IllegalArgumentException("proxyHostPlusPort string is expected in 'host:port' format");

        String[] hostPlusPort = proxyHostPlusPort.split(DELIMITER);

        setProxy(hostPlusPort[0], new Integer(hostPlusPort[1]).intValue());        
    }

}

Now, if you notice the piece of code above setProxyHostPlusPort and getProxyHostPlusPort follow the javabean contract and set and get the same type which is “String”. We can now use this class in our spring context as a bean that we shall inject onto our HttpClient bean as shown below:

...
...

<!-- Here is a relevant section of Spring Context -->
    <bean id="reqSender" class="mypackage.RequestSender">
       <property name="messageFactory">
         <bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
       </property>
       <property name="messageSenders">
         <list>
            <ref bean="httpSender" />
         </list>
       </property>
       <property name="marshaller" ref="myMarshaller" />
       <property name="unmarshaller" ref="myMarshaller" />
       <property name="defaultUri" value="http://webservice-url/deployed/at/some/server" />
    </bean>

    <bean id="myHostConfig" class="mypackage.MyHostConfiguration">
        <property name="proxyHostPlusPort" value="192.168.1.111:8080" />
    </bean>

    <bean id="httpParams" class="org.apache.commons.httpclient.params.HttpClientParams">
      <!-- Timeout in milliseconds: in this case 2 minutes -->
      <property name="soTimeout" value="120000" /> 
    </bean>

    <bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
      <!-- hostConfiguration set to myHostConfig that sets the proxy host and port as shown above -->
      <property name="hostConfiguration" ref="myHostConfig" />
      <property name="params" ref="httpParams" />
    </bean>

    <bean id="httpSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
      <constructor-arg>
        <ref bean="httpClient"/>
      </constructor-arg>
    </bean>    

    <bean id="myMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" >
      <property name="contextPath" value="path_to_directory_with_jaxb_xml_generated_classes"/>
    </bean>
...
...

As you see in the example spring context above, we have used myHostConfig to set our poxy host and port and later injected this config onto our HttpClient. You can comment hostConfiguration property line of http client definition if you don’t want to use proxy for this connection. Similarly you can choose not to set the timeout for this connection by commenting params property line that sets HttpParams onto this HttpClient.

~srs

soapUI Tips n Tricks – Part 1

soapUI is a nice little web services testing tool. While working with it, I came across many “gotcha” moments. Life would be perfect without “gotchas”, ain’t it? Apparently, we live in a real world which is not so perfect and we have to work around the problems at times and get ahead. Over period of time, I came across some problems in soapUI and figured out a solution / work-around to those problems. I thought it would be nice to document those as and when I come across those. So here I am documenting these in part 1. I say “part 1” because I anticipate many more problems and work-arounds to these to come in the near future as soapUI matures through its releases.

[Please note: the tips listed below, may or may not apply to your particular case, as it is highly possible that a problem in one version of soapUI is fixed in the next. Nevertheless, it helps having a list of these at hand in case yours happens to be one of them and for some reason, you don’t want to upgrade to the next release]

  1. I changed my SOAP Request as per new schema definition, Why do I still get “Schema Compliance” FAILED error?

    soapUI, by default, locally caches wsdl and schema definitions. You can change this behavior in soapUI’s preferences. In any case, if the web service schema changes on server, you need to right click on a given Binding and click on “Update Definition”. This will pop up a window where you can give the exact address of the web service which you would test your Binding and all requests associated with this Binding with. Once you update definitions all your requests shall start working fine.

  2. When I click in error log area, soapUI hangs !

    This was a known issue in soapUI 2.0.2. It probably is fixed in the releases afterwards. Best thing is do not click in error log trying to reach the exact location of error ( as you might be used to in your IDE ). Other alternative is to upgrade to newer release of soapUI.

  3. I am using xmlHolder object from groovyUtils. But xmlHolder.setNodeValue does not work! How do I set values on xml holder nodes?

    I found this problem in soapUI 2.0.2 again. Here is a workaround, instead of using syntax

    xmlHolder.setNodeValue(“//ns:books[1]/ns1:book[1]/ns1:Id[1]”, “1234”);

    use following syntax

    xmlHolder[“//ns:books[1]/ns1:book[1]/ns1:Id[1]”] = “1234”;

  4. I am using built-in context variable ‘projectDir’ and it gives me NullPointerException when I run the project using command line tool ‘testrunner.sh’ !

    It seems ‘projectDir’ variable does not work when running project at command line. You have to use following technique instead:

    def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )

    //and then use
    groovyUtils.projectPath

  5. I use soapUI on Mac. Somehow ‘CMD + C’ and ‘CMD + V’ does not work for copy and paste respectively!

    This was the weirdest behavior I came across in soapUI. There is a workaround though. I think soapUI gets confused between usual windows ‘Ctrl’ key and Mac ‘Ctrl’ key. So try ‘CTRL + C’ and ‘CTRL + V’ instead of ‘CMD’ key. Also sometimes, you might have to do ‘Ctrl + C’ and then to paste you might need to use ‘CMD + V’. But you get the point, try ‘Ctrl’ and ‘CMD’ keys interchangeably and you will get the desired behavior depending on your objective at that time.

  6. I cannot refer to testRunner object in my groovy assertion. How do I access a test-case or step therein from my groovy assertion?

    This was quite an interesting one. typically when you want to access a current test case you would use a syntax

    testRunner.testCase

    this works perfectly fine in a plain groovy step or setup or tear down scripts. However, when you try referring to testRunner within a groovy assertion step, soapUI throws exception. The workaround to this is accessing testCase or test step via ‘context’ object. So you can use a syntax

    context.getTestCase().getTestStepByName(“MyStep”) OR
    context.getTestRunner()

    depending on your need.

  7. I opened up ‘preferences’ and changed some property. Now all my requests are failing !

    This was a bug in soapUI 2.5.1. What happens is the moment you open up ‘preferences’ and change anything. Doesn’t matter what it is that you changed, the ‘HTTP Version’ property under ‘Preferences > Http Settings Tab’, by default changes from 1.1 to 0.9. This makes all your SOAP requests fail. The workaround is open up ‘Preferences > Http Settings Tab’ and change ‘HTTP Version’ property to ‘1.1’ OR simply refrain from using 2.5.1 and go back to good old version of soapUI that was working for you 🙂

  8. soapUI inserts double xml ending tags in SOAP Requests!

    If your xml schema has a sequence of elements where ‘either or’ condition exists, soapUI somehow creates a double set of ending tags for one of the elements. For example: say your schema accepts either element or under a node as shown below:

    <person>
      <licenseNumber>12345678</licenseNumber>
      <!-- OR -->
      <memberNumber>LIB-333</memberNumber>
    </person>
    

    When you try to create default SOAP Request that has ‘person’ element OR even if you double click on existing SOAP Request (that you might have crafted very carefully) having ‘person’ element in it, soapUI somehow inserts one more ending tag for ‘licenseNumber’ or ‘memberNumber’ depending on whichever you are using. So for example, soapUI changes xml element in your request to look like:

     <licenseNumber>12345678</licenseNumber></licenseNumber> OR
     <memberNumber>LIB-333</memberNumber></memberNumber>
    

    Naturally you are not aware that soapUI changed this element behind the scenes and you try to run this request and things just don’t appear to work the way they used to. The workaround to this problem is that do not double click on SOAP Request that you have already crafted carefully unless you really need to modify it. Of course, pay attention to elements that are ‘either or’ type in schema and you might need to manually adjust them if soapUI changes those behind the scenes. This was a very annoying bug in soapUI 2.0.2. However this has been fixed in soapUI 2.5 onwards. So your other alternative is to move to newer version of soapUI.

  9. How do I flash ‘alert’ type of UI message box within my groovy script execution?

    Many of you might already know the answer to this but I thought of adding this to the list because I don’t think its documented. You can use ‘com.eviware.soapui.support.UISupport.showInfoMessage’ to flash an alert type of message to the user from a groovy script within soapUI. For example:
    com.eviware.soapui.support.UISupport.showInfoMessage(‘Sorry, you cannot execute this script unless database properties are set.’);

  10. How do I pretty print xml programmatically within my groovy script in soapUI?

    Many times you will need to capture request or a response or a part of it to an external file for a later review. You can do this within your groovy script in very many different ways that I perhaps cannot cover in this post. However, the xml string that you write to the file may not be ‘pretty’ formatted and indented. You can certainly make use of built-in soapUI object com.eviware.soapui.support.xml.XmlUtils to do this for you. For example, in your groovy script:

    ...
    def xmlUtils = new com.eviware.soapui.support.xml.XmlUtils()
    ...
    //Say 'str' is the xml string you want to 'pretty' print
    //Format xml for easier viewing
    def prettyString = xmlUtils.prettyPrintXml(str)
    //Now use 'prettyString' string to write to a file or any other use that you might have 
    

    In fact there are many more methods on XmlUtils object that you can make use of. Refer to soapUI javadocs in order to understand how XmlUtils can help you.

I guess that’s it for part 1. Hope that helps till I come up with part 2.

~srs

How to set socket timeout using Spring WebServiceTemplate?

If you are using Spring for web services, there is a high probability that you have one of your classes extending WebServiceGatewaySupport class provided by Spring. This class has a method getWebServiceTemplate() that returns a WebServiceTemplate class on which you can invoke your requests to send and receive http requests. Typically, your code would look like:

public class RequestSender extends WebServiceGatewaySupport {
...
...
public void send(SomeWebServiceRequest request) {
    SomeWebServiceResponse response = getWebServiceTemplate().marshalSendAndReceive(request);
}
...
...
}

Now, what if the server takes too long to respond? In that case, you shall receive a SocketTimeoutException. There is a way, though not direct, to set timeout using WebServiceTemplate so that your request does not timeout due to slower server response. Here is how you can do it ALL WITHIN SPRING CONTEXT. All you need is commons-httpclient. Assuming you are using maven, first you need to include a dependency on commons-httpclient as shown below:

        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>

Including dependency above gives you access to HttpClient() class that we will use to set timeout. Once we have HttpClient with timeout set we shall inject this onto CommonsHttpMessageSender. It is this message sender that we are then going to inject onto WebServiceTemplate. Everything done via spring context config shown below:

...
...

<!-- Here is a relevant section of Spring Context -->
    <bean id="reqSender" class="mypackage.RequestSender">
       <property name="messageFactory">
         <bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
       </property>
       <property name="messageSenders">
         <list>
            <ref bean="httpSender" />
         </list>
       </property>
       <property name="marshaller" ref="myMarshaller" />
       <property name="unmarshaller" ref="myMarshaller" />
       <property name="defaultUri" value="http://webservice-url/deployed/at/some/server" />
    </bean>

    <bean id="httpParams" class="org.apache.commons.httpclient.params.HttpClientParams">
      <!-- Timeout in milliseconds: in this case 2 minutes -->
      <property name="soTimeout" value="120000" /> 
    </bean>

    <bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
      <property name="params" ref="httpParams" />
    </bean>

    <bean id="httpSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
      <constructor-arg>
        <ref bean="httpClient"/>
      </constructor-arg>
    </bean>    

    <bean id="myMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" >
      <property name="contextPath" value="path_to_directory_with_jaxb_xml_generated_classes"/>
    </bean>
...
...

Well, hope that saves you hours of frustration trying to figure out how to set timeout in order to handle slow server response.

~srs

Reusable SQL Connection in soapUI

No matter how modern the systems get, we always often have some level of interaction with databases whether for reporting purposes or for recording transactions. In typical web services testing, one would imagine testing xml response to a given xml payload. What if, you need to connect to a database and say, verify, if a particular record was inserted by firing a select query? OR if, you need to create a log of your testing right inside the database? If not you may need to fire a select query after each SOAP Request, right in the Groovy Assertion Step of that request.

Now, quick and dirty way would be to create a SQL connection each time you need a connection and close it once you are done with it. Creating and closing a resource connection is very expensive. Hence, this could prove very costly when you are testing thousands of SOAP Requests. Imagine for each request you fire if there is a connection created whether in Groovy Assertion step or otherwise! I shall try to go over a simple mechanism to create a common reusable connection right at the beginning of your soapUI TestCase and then recycle it once you don’t need it.

The example I am trying to illustrate shall be useful when you have a single soapUI test case that, say, is iterating over number of rows from a datasource, carrying out some number of test steps and at each test step, before the step or after that step you need to connect to the database and carry out some operation.

To begin for any RDBMS you need four things: Driver, URL, Username and Password.
1. You can store these as TestCase properties, say, “dbUrl”, “dbDriverClassName”, “dbUser”, “dbPassword”
2. Each soapUI test case has two scripts: Setup Script and TearDown Script. We shall make use of these two scripts in order to illustrate our example. Inside Setup Script we shall obtain handle to our common connection as shown below:

//In a Setup Script
import groovy.sql.Sql

//try to create connection to database, if available. load this connection on context
//if not, log error and continue
//In order for this to work, you need to have jdbc driver jar file in $SOAPUI_HOME/bin/ext folder
def url = context.expand( '${#TestCase#dbUrl}' )
def driver = context.expand( '${#TestCase#dbDriverClassName}' )
def user = context.expand( '${#TestCase#dbUser}' )
def password = context.expand( '${#TestCase#dbPassword}' )

if ( (null != url) && (null != driver) && (null != user) && (null != password) ) 
{
  try {
    connection = Sql.newInstance(url, user, password, driver)
    context.setProperty("dbConn", connection)
  } catch (Exception e) {
    log.error "Could not establish connection to the database."
  }
}

3. Now wherever we need access to this connection in any of our test steps: whether in Groovy Assertion or in Groovy Script, we simply check for existence of this property on the soapUI context, for example, say following Groovy Assertion verifies if a customer account was created in the database right after SOAP Request CreateCustomer.

  //In a Groovy Assertion Step of a SOAP Request
  def MSG_CUSTOMER_NOT_FOUND = "Customer not found!"
  // Obtain customer number from response of a SOAP Request that creates a customer
  def customerNumber = <... groovy code retrieving customer number from response here ...> 

  //Check if connection to database is available
  if (context.dbConn)
  {
    //connection to the database
    def sql = context.dbConn

    row = sql.firstRow("select count(*) as numOfRecords from customers where customer_number = ? ", [customerNumber])

    //Verify that customer record exists in Customer Table in the database
    assert ( 1 == row.numOfRecords ):MSG_CUSTOMER_NOT_FOUND
  }

4. Finally, in TearDown Script, we close the connection:

//In a TearDown Script
//Close db connection
if (context.dbConn)
{
  context.dbConn.close()
  log.info "Closed Database Connection."
}

Ain’t that simple and reusable? Of course, you can extend this idea to create a connection pool or any other advanced set of objects, map of objects that you can hold onto soapUI context and use whenever needed. However, do not forget to clear up these resources though. That is what the TearDown Script is for!

~srs

How to insert a node in soapUI property transfer step using XPath and XQuery

I have been using soapUI Pro for testing web services for a while now. soapUI is a neat tool for web services testing. However, it lacks fair amount of documentation. During my hands-on time with soapUI I learnt a lot of tricks and tips that I think I can share with you in order to save you some frustration that I went through.

In this post, I shall go over how to insert an xml node in soapUI property transfer step. Property transfer is a test step that allows you to transfer data from one xml request or response to another. For example, say you execute a request to search for a book and the response of this request is a number of xml book nodes. The next request you want to issue is to buy a book. In next request you need one of the book nodes obtained in the response of previous request. Following flow of events can help understand this scenario.

-> Issue a “searchBook” request for a book
-> results in a “searchBookResults” of xml book nodes
-> select one of these nodes and submit it in “buyBook” Request

In the scenario above you can use soapUI’s property transfer step to transfer an xml “Book” node from “searchBookResults” to “buyBook” request. For transferring basic node data like text() or attribute values you can refer to soapUI’s documentation at

http://www.soapui.org/userguide/functional/propertytransfers.html

Assuming you are familiar with basic soapUI Property Transfer, Iet’s try to understand how exactly we can achieve a node transfer of the kind listed above with example xml requests:
[Note: for the sake of simplicity I am not using namespaces in this example]

Sample Book Search Request:

<searchBook>
 <searchName>Design Patterns</searchName>
</searchBook>

Sample Book Search Results:

<searchBookResults>
 <book>
  <id>1234</id>
  <name>Design Patterns</name>
  <author>John Doe</author>
  <desc>A good book on design patterns</desc>
<paymentDetails>
    <totalPrice>30.00</totalPrice>
  </paymentDetails>
 </book>
  ...
  ...
  ...
</searchBookResults>

Sample Buy Book Request to be created:

<buyBook>
 <book>
  <id>1234</id>
  <name>Design Patterns</name>
  <author>John Doe</author>
  <desc>A good book on design patterns</desc>
<paymentDetails>
    <totalPrice>30.00</totalPrice>
    <!-- Optional Element that needs to be inserted only at the buy SOAP Requst -->
    <frequentBuyerCard>BN-987654321</frequentBuyerCard>
  </paymentDetails>
 </book>
</buyBook>

Case I
Now let’ see a simple property transfer that transfers the entire book node with id=1234:

Property Transfer Source Window Code Looks like:

//bookSearchResults/book[id/text()='1234'][1]

If you notice above ‘id/text()=’1234’ sets the selection criteria and [1] selects the first node in an array of nodes matching the criteria. Also do not forget to check option “Transfer Child Nodes” in your property transfer. This makes sure that entire tree below the node being transferred is transferred to the target.

Property Transfer Target Window Code Looks like:

//buyBook[1]/book[1]

Its important that your target SOAP Request has an empty ‘book’ node under the ‘buyBook’ node. Unless your target request has a node, property transfer shall not be able to transfer anything from source to target. For example, in case below if you did not have empty ‘book’ node, property transfer would complain that book[1] node is missing!

Case II
Now the real deal ! What if you want to insert that optional node shown in buyBook Request above? This optional node is buyer’s frequent buyer card number that needs to be submitted along with buyBook request so that appropriate club points are deposited to this card number as a result of this transaction.

Here is how=>

First you would have to transfer the node as shown above in a property transfer, say, “TransferBook”. So typically your test case shall have following steps in that order:

1. SearchBook – SOAP Test Request Step
2. TransferBook – Property Transfer Step (Its source is Search Results and target is buyBook Request)
3. BuyBook – SOAP Test Request Step

Now you shall create a new Property Transfer Step, say, “InsertCard” and your sequence of steps shall now look like:

1. SearchBook – SOAP Test Request Step
2. TransferBook – Property Transfer Step ( At end of this step we would have simple buyBook request )
3. InsertCard – Property Transfer Step ( At end of this step we would have inserted card node in buyBook request )
4. BuyBook – SOAP Test Request Step

[note: InsertCard property transfer step’s source is buyBook SOAP Request step’s Request and its target is also buyBook SOAP Request step’s request as we are modifying the existing node in buyBook request]

Property Transfer Source Window Code when inserting a node:

let $x:= //buyBook[1]/book[1]
 return
<book>
  <id>{$x/id/text()}</id>
  <name>{$x/name/text()}</name>
  <author>{$x/author/text()}</author>
  <desc>{$x/desc/text()}</desc>
<paymentDetails>
    <totalPrice>{$x/paymentDetails/totalPrice/text()}</totalPrice>
    <frequentBuyerCard>BN-987654321</frequentBuyerCard>
  </paymentDetails>
</book>

If you notice above, all we are doing is recreating the book node and populating its children elements and nodes up until we come across payment details where we hard code our frequentBuyerCard node ( that is insert it at this point ), the return statement returns this entire book node to be transferred to target ( which in this case is same as before : the very same node from buyBook request ). Do remember to check ON the option “Use XQuery” in this property transfer.

Property Transfer Target Window Code when inserting a node:

//buyBook[1]/book[1]

A better way to insert a node like shown above using XQuery is by issuing a statement like

insert node abcd as last into $x

This way one need not re-create the entire node. However soapUI Pro (2.5) as of this writing does not support this behavior. i.e. dynamic insert/updates using XQuery.

Update – Feb 17, 2009:
As per soapUI support, it seems soapUI 2.5 Pro currently uses Saxon 9 XQuery processor and Saxon 9.1 supports the the dynamic insert as I discussed a few lines above. So I hope in the future, the newer version of soapUI Pro using Saxon 9.1, shall be able to support actual dynamic insert of nodes. So watch out for soapUI’s newer version that may use Saxon 9.1 !

Hope that helps.

~srs

Where in Spring is Jaxb2Marshaller?

I just answered this question for myself after some frustration reading through Spring documentation. I was trying to use Jaxb2Marshaller implementation provided by Spring. Had a real hard time finding where exactly this class is located in Spring Jars.

Spring WS Tutorial – Chapter 8

gives a fair idea to the reader about marshalling, unmarshalling and how to inject marshallers into WebServiceTemplate etc. But it does not say where Jaxb2Marshaller is. I use Maven for building my project and in Maven you must include artifact dependency:

        <dependency>
            <groupId>org.springframework.ws</groupId>
            <artifactId>spring-oxm-tiger</artifactId>
            <version>1.5.4</version>
        </dependency>

in order to use Spring WS Jaxb2Marshaller. If you are using Jaxb1Marshaller you would be ok with just plain “spring-ws-core” artifact as your dependency. Hope this saves some frustration to some of my readers trying to find out the answer to the very question, I made into a title of this post!

~srs