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

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 find if a date-time is in given time slot in Groovy?

Groovy has concept of a range. You can define, say, a range of numbers, for example: try running following piece of code in groovy console:

def numRange = 1..5
numRange.each{println it}

Console output shall be:
1
2
3
4
5

Let’s use the concept of range to find out if a date time provided is in given range of date times / given time slot. Without much explanation, let’s just dive into the code:

df = new java.text.SimpleDateFormat("yyyyMMddHH:mm:ss")
//Dec 31st, 2009 at 10:00 pm
date1 = df.parse("2009123110:00:00")
//Jan 1st, 2010 at 10:00 am
date2 = df.parse("2010010110:00:00") 

println "From: ${date1}"
println "To: ${date2}"

def slot = date1..date2

//Date time in range: Jan 1st, 2009 at 1:00 am
dateTimeInRange = df.parse("2010010101:00:00")
println "Test date time in range: ${dateTimeInRange}"
dateTimeOutOfRange = df.parse("2010010110:05:00")
//Date time out of range: Jan 1st, 2010 at 10:05 am
println "Test date time out of range: ${dateTimeOutOfRange}" 

assert true == slot.containsWithinBounds(dateTimeInRange)
assert false == slot.containsWithinBounds(dateTimeOutOfRange)

The console output shall be:
From: Thu Dec 31 10:00:00 EST 2009
To: Fri Jan 01 10:00:00 EST 2010
Test date time in range: Fri Jan 01 01:00:00 EST 2010
Test date time out of range: Fri Jan 01 10:05:00 EST 2010

Alright. So now, if you did not know earlier, you know how to play with ranges in groovy. Have fun with groovy ranges!

~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