Well, I think it is clear now I am a big fan of SoapUI. So here is another post about it. This time I explain how you can use it to perform a load test for your webservice and how to work around a common issue with this test. One of the business rules we have is that a message may only be processed succesfully once. To implement this, a unique referenceNumber is supplied in the body of the SOAP message (I know, it was better to use a policy for that by adding a SOAP header, but this is a piece of legacy I have to deal with). In the webservice (actually in a XFire handler) the referenceNumber is checked against all processed referenceNumbers in a database and if it already exists, a fault message is returned.
To avoid this fault message in our load test we added several steps to our Soap UI testcase that increases this referenceNumber, so it's unique for every message.
Here is an example of how to do this. First I created a webservice that just echoes the inputted string. Here is the WSDL:

XML:
  1. <wsdl:definitions targetNamespace="http://net.pascalalma.services/EchoService">
  2. <wsdl:types>
  3.   <xsd:schema targetNamespace="http://net.pascalalma.services/EchoService" elementFormDefault="qualified" attributeFormDefault="qualified">
  4.     <xsd:element name="s" type="xsd:string"/>
  5.     <xsd:element name="echoAnswer" type="xsd:string"/>
  6.   </xsd:schema>
  7. </wsdl:types>
  8. <wsdl:message name="echoRequest">
  9.   <wsdl:part element="tns:s" name="s"/>
  10. </wsdl:message>
  11. <wsdl:message name="echoResponse">
  12.   <wsdl:part element="tns:echoAnswer" name="echoAnswer"/>
  13. </wsdl:message>
  14. <wsdl:portType name="EchoService">
  15.   <wsdl:operation name="echo">
  16.     <wsdl:input message="tns:echoRequest" name="echoRequest"/>
  17.     <wsdl:output message="tns:echoResponse" name="echoResponse"/>
  18.   </wsdl:operation>
  19. </wsdl:portType>
  20. <wsdl:binding name="EchoServiceHttpBinding" type="tns:EchoService">
  21.   <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
  22.   <wsdl:operation name="echo">
  23.     <wsdlsoap:operation soapAction="urn:echo"/>
  24.     <wsdl:input name="echoRequest">
  25.       <wsdlsoap:body use="literal"/>
  26.     </wsdl:input>
  27.     <wsdl:output name="echoResponse">
  28.       <wsdlsoap:body use="literal"/>
  29.     </wsdl:output>
  30.   </wsdl:operation>
  31. </wsdl:binding>
  32. <wsdl:service name="EchoService">
  33.   <wsdl:port binding="tns:EchoServiceHttpBinding" name="EchoServiceHttpPort">
  34.     <wsdlsoap:address location="http://localhost:8080/XFireTest/services/EchoService"/>
  35.   </wsdl:port>
  36. </wsdl:service>
  37. </wsdl:definitions>

I then created a TestCase based on this WSDL and added four steps:

  • A properties step
    In this step a property is defined to be used in this TestCase.
  • A Groovy Script step
    This step has the logic to increase the property that is defined in the step before.
  • A Transfer step
    With this step we copy the value of the (modified) property into the SOAP request before we send it to our webservice.
  • The SOAP request step
    Final step is sending the request with the modified value.

Now when all this is in place you can run a simple loadtest like this:
MyLoadTest

In the server where my webservice is running you will get out put like this:
Output webservice
As you can see each call gets a unique number.

Now we change the LoadTest to have multiple threads accessing the webservice at the same time. When we do that like this:
MyLoadTest with multiple threads

the output becomes:
Output Webservice Multiple Threads

Now the generated numbers are no longer unique!

To fix this I have added a property and changed the Groovy Script Step so it adds the thread index to the unique part. The Property Step and the Groovy Step become like:
New Properties Step
and
New Groovy Step

And the output now is:
Output Webservice Correct

Now that looks better, doesn't it? All generated ID's are unique again for every message.