Reusing a database connection in soapUI

Creation of a database connection is a rather resource heavy task. Depending on the way your soapUI test cases are implemented there might potentially be a large number of different calls to an underlying database. When running test cases or test suites the connection shall preferably only be created once and then be reused whenever needed. Though on the other hand when debugging test cases a single test step might need to be executed in its own context without an existing database connection. Below I’ll highlight a short example that will combine the two and which will make it rather smooth to reuse and create a database connection when needed.

Solution

A reusable database connection in;

  • test cases
  • test suites
  • test steps

The example below assumes that the code for setting up a database connection is already in place. If not setting up the database connection using SQL server with jtds can be found here.

How

The trick is really to use the soapUI context as a placeholder for the database connection object. Whenever a connection is established the connection shall be stored in the context so that it does not matter if a full test suite or a single test case is executed, the context variable will hold the DB connection. For execution of single test steps the connection needs to be created every time, sorry no workaround here.

Modularization (sort of)

Since this example references to the free version of soapUI, modularization is simply re-execution of a test step and a way of avoiding duplicate code lines. Assume a test case like the one below.

SoapUITestCase
  \- SetupDatabaseConnection
  \- TestRequest (SOAP)
  \- RunADatabaseQueryTestStep

The test step SetupDatabaseConnection is must preferably be present in all test cases (it is possible to include test cases in test cases) where a database connection shall be shared, it can if wanted even be disabled. The modularization in effect simply invokes the SetupDatabaseConnection test step from the query test step when needed i.e. when no connection exists.

Setup database connection test step

/* Groovy */
if (context.sqlconn == null) {
  // Create the database connection. This wont be needed in the following cases
  // 1) The running test suite context alread has a sql connection created and stored
  // 2) The running test case context alread has a sql connection created and stored
  ...
  def sql = Sql.newInstance("jdbc:jtds:sqlserver://"+dbIp+":"+dbPort"+"/"
  +dbName,dbUserName,dbUserPassword, "net.sourceforge.jtds.jdbc.Driver")
  context.setProperty("sqlconn", sql)
}

Running a database query test step

/* Groovy */
if (context.sqlconn == null) {
  // Recreate a database connection here since the
  // context is only alive for a test case execution
  // not for executing single test steps.
  testRunner.runTestStepByName("SetupDatabaseConnection")
}
if (context.sqlconn != null) {
  def res = sql.eachRow("select * from Users", {
    userId = it.UserId
  })
}

So by storing away the database connection in the current context and by using a simple switch the same connection can be resused all over and at the same time be created only a needed basis.

Advertisements

Extending WebTest for FitNesse and Selenium

WebTest is Selenium wrapper used in FitNesse test cases. It contains a number of methods that makes it easy to write GUI based test. However it only supports a limited number of methods (WebTest reference) and in most cases there is a need for tweaking these or simply adding new ones.

Extending the com.neuri.webfixture.WebTest class should be a simple thing to do if it had not been for the private Selenium instance attribute.

This short post will describe an approach for how to be able to extend the com.neuri.webfixture.WebTest class, the example is based on webtestfixtures version 2.01.

Using reflection to get the selenium instance

For all calls to the Selenium RC API to work the Selenium instance hidden in the super class needs to be used. This instance can only be fetched using reflection. Add the method below to your extending class and you will get access to the Selenium instance simply by calling getSeleniumInstance()


protected Selenium getSeleniumInstance() {
  try {
    Field privateInstance = com.neuri.webfixture.WebTest.class.getDeclaredField("instance");
    privateInstance.setAccessible(true);
    Selenium seleniumInstance = (Selenium) privateInstance.get(this);
    return seleniumInstance;
  } catch (NoSuchFieldException ndfe) {
    // Do nothing!
  } catch (IllegalAccessException iae) {
    // Do nothing!
  }
  return null;
}

Usage example
Retrieve the Selenium instance and you have access to the Selenium RC API, in the example below getTitle().


public class UnitTHWebTest extends com.neuri.webfixture.WebTest {
  protected Selenium getSeleniumInstance() {...}

  public boolean pageContainsTitleText(String text) {
    Selenium si = getSeleniumInstance();
    if (si.getTitle().equalsIgnoreCase(text)) {
      return true;
    } else {
      return false;
    }
  }
}

Download from:

soapUI inline request parameterization made simple using static Java methods

Maintainability and reuse when using a lot of Groovy scripting or in-house Java libs with the free version of soapUI can be really cumbersome. The same groovy code snippets are all over the place, it does not matter if a lot of core functionality is mapped into the java libraries there are still some Groovy code to be written to get this to work in the long run.

I recently had to struggle creating maintainable test suites covering more than 200 test cases and in total easily more than a thousand different requests. There was a clear need for making the test suites easy to maintain and extend. Removing all the duplicated Groovy code was the top priority. Blow is the usual scenario we had for the majority of our tests in the beginning.

A) Groovy script

  • importing any bin/ext java libraries
  • invoking a given method the e.g. creates a timestamp value
  • put the generated timestamp into a test case property

B) Test request

  • inline expansion of the test case property

This was really an overkill approach when dealing with hundreds and hundreds of different test requests. So how to get this in to small one-liners inside the requests directly without even having to deal with test case properties asf..

Using static Java methods

Just implement a set of static Java methods and inline these in your test requests. No need for library imports or instance creation just call the method needed with arguments that in turn can be dynamically created.

Below is an example class that can be added to a jar file put in the soapUIinstallation/bin/ext folder.


public class TimeStampCreator {
  public static String getToday() { ... }
  public static String getTodayPlusDays(int days) { ... }
  public static String getTodayMinusDays(int days) { ... }
}

The methods above can be called accordingly as described in the TestRequest (SOAP) example below, note the nested test case parameter expansion.


<args xsi:type="api:ArrayOf_xsd_string" soapenc:arrayType="xsd:string[]">
  <item>${=package.name.TimeStampCreator.getToday()}</item>
  <item>${=package.name.TimeStampCreator.getTodayPlusDays(2)}</item>
  <item>${=package.name.TimeStampCreator.getTodayMinusDays(${#TestCase#days})}</item>
</args>

Works like a charm…