September 2, 2014

dynamic query parameters in SoapUI

Filed under: automation — SiKing @ 1:49 pm

The other day I needed to create a REST call in SoapUI that had a parameter of the form multi[<multi_type>][<combins>]=<stake>. Everything in the trig-brackets is a variable. This is a perfectly valid URI and hence perfectly valid REST, but not very common and hence SoapUI has no clue how to handle this. After some discussions with SoapUI staff, the solution ended up being rather trivial.

You have to create a new event handler. This is a -Pro only feature, and if you are not sure how to set one up have a read through the documentation before continuing.

The event type that I used is SubmitListener.beforeSubmit. Apparently RequestFilter.filterRequest would do the job as well, but this event listener is broken in older versions of SoapUI … such as the one that I am still running. :/ In order to make things cleaner, I also set my target filter to .*multibet.*.
You have to get all three variables from somewhere. I chose to keep them in TestCase properties; at run time you can set them any way you chose, such as property transfer.
The event code ends up being:

def multi_type = context.expand('${#TestCase#multi_type}')
def combins = context.expand('${#TestCase#combins}')
def stake = context.expand('${#TestCase#stake}')
def multi = submit.request.addProperty("multi[$multi_type][$combins]")
submit.request.setPropertyValue(, stake)

Note that this will actually modify the method in your service endpoint, which could mess up any other calls in your test suite. To clean this up, create a second event, of type SubmitListener.afterSubmit, probably same target if you are using one, with the code:

def multi_type = context.expand('${#TestCase#multi_type}')
def combins = context.expand('${#TestCase#combins}')

Simple, right? But wait, it gets better! :mrgreen:

I thought this same approach could be used to solve a problem SoapUI has had like for ever – and yes SmartBear, this is a problem! Array parameters; the problem has been discussed in various places.

At first I tried some kind of loop, where I did multiple submit.request.addProperty() each followed by submit.request.setPropertyValue(), but only the last one actually took. This proved that SoapUI does not support this at the object level (and not just at the GUI level), in which case the enhancement from them is probably not going to be trivial.

Again start by creating a SubmitListener.beforeSubmit. The toughest part here is deciding how you are going to mark the parameter and pass the values that need to be processed. There are two methods in the API that give you access to all the call parameters: submit.request.getPropertyList() and submit.request.getProperties(); each of these is broken in different ways in different older versions of SoapUI. :???:

Some options that I experimented with are:

  • Pass the values looking like an array, something like [1, 2, 3].
    submit.request.getPropertyList().each {
    	// extract the Array parameter name and array of values
    	def arrParamName
    	def arrParamValues = []
    	if(it.value.contains('[')) {
    		arrParamName =
    		arrParamValues =	// converts a String to an ArrayList
    	// wasn't an array
    	if(arrParamName == null)
    	// convert the array of values into multiple name-value pairs ... discussed below

    This has the problem what if you want to pass the literal string [1, 2, 3]? Also, it seems too verbose.

  • Somehow specially marking the parameter and still pass the values looking like an array. When you define your method and its parameters, there are several things that you can define about it. In order for any of this to work you need to set Disable Encoding. Have a look at the reference; we are talking about control number 13.
    submit.request.getProperties().each {
    	// convert the array of values into multiple name-value pairs ... discussed below
  • Alternatively, set the Type (control number 10) to something unique.
    submit.request.getProperties().each {
    	// convert the array of values into multiple name-value pairs ... discussed below

Now to convert the array of values into multiple parameters. So if your parameter name-value looks like foo=[1, 2, 3] you want to end up with foo=1&foo=2&foo=3. We already have the first "foo=", we just need to create the rest of this:

def arrParamName = it.key
def arrParamValues =	// yes, .value twice!
def nvPairs = new StringBuilder()
nvPairs << arrParamValues.remove(0)
arrParamValues.each {
	nvPairs << '&'
	nvPairs << arrParamName
	nvPairs << '='
	nvPairs << it

Now you need to pass this string undecoded to the original parameter.

submit.request.setPropertyValue(arrParamName, nvPairs.toString())

If the parameter is already set to Disable Encoding, then the first line above is not needed.

This solution is not perfect, but hopefully it is enough to at least get you going.

June 27, 2014

Simple Web Crawler

Filed under: automation — SiKing @ 3:19 pm

In some Selenium discussion fora, I often see a question how do you build a web crawler / link checker in Selenium. The short answer is: you don’t! The more lengthy answer is: you pick a different tool / library that is better suited for the job.

First, let me cover why Selenium is a (very) poor choice. Selenium is a tool that interacts with web applications, specifically, it interacts with DOM elements in a web browser. Some links on any given website are going to lead to non-DOM pages: download links, directory listings, etc. In all these cases Selenium just throws up its hands and gives up!


One very excellent library is HTTPBuilder. My implementation of HTTPBuilder crawler is available on SourceForge. (It’s documented inline, so I am not going to repeat myself here.) In fact, many so called Selenium web crawlers only use Selenium to open a page, but use HTTPBuilder to parse the page status … which makes Selenium just unnecessary overhead.

There are a few things that my example crawler does not handle; the exact solution for these edge cases is left as an exercise for the reader. ;)


Just for kicks, I tried to do this in SoapUI. It took a bit of convincing, but it can be done.

If you look at the links on most websites, you will find a mixture of complete URL (server and everything) and paths local to that server. The biggest challenge is to dynamically overwrite the endpoint of a SoapUI REST request. Below is only one possible solution.

First step is to create a new project, new REST service, new Resource, and a new GET Method. For all the prompts only set the endpoint to ${#TestCase#endpoint}.

crawler service

Now create a new testsuite, and a new testcase. The testcase has two properties: baseURL and endpoint. baseURL is going to hold the starting URL of the page you want to check; endpoint will eventually hold the URL of the link you are currently checking.

First test step is going to be a REST call to the baseURL. If you remember we set our Endpoint in the REST service to the literally ${#TestCase#endpoint}. So we need a testcase Setup Script:

testCase.setPropertyValue("endpoint", context.expand( '${#TestCase#baseURL}' ))

Run the first test step, and create an assertion for Valid HTTP Status Codes to be 200, to make sure that we get something back.

Next we want to extract all the links. This is done with a DataSource ste; set the type to XML, Source Step to your previous step, and Source Property to ResponseAsXml. Row XPath to select all the elements will be //*:a[exists(@href)]; this will filter out only anchors that actually have an href attribute. The column will be @href and the property name can be anything, I used “href”. Run it and make sure you are getting the links from your previous step.

After that will be a Groovy step to parse and transform what we just retrieved:

def location = new URI(context.expand( '${anchors#href}' ))

if(location.scheme == null) {
	testRunner.testCase.setPropertyValue("endpoint", context.expand( '${#TestCase#baseURL}' ) + context.expand( '${anchors#href}' ))
} else {
	testRunner.testCase.setPropertyValue("endpoint", context.expand( '${anchors#href}' ))

Note that my DataSource step was called “anchors”. I am using URI(), which breaks the string up into individual components that can I refer to as I need without doing any fancy String manipulations.

At this point it might be necessary to review exactly what is a URI and what is a URL. The big deal, tested in the if statement above, is whether it start with something like “http” or not. If not ( == null), then we have a local path and we have to prepend the server name in front of it from our baseURL. If yes, then it’s a complete link to some other server, so we take it as is. The result is assigned to the testcase property endpoint.

Note that just as in the case of HTTPBuilder above, this does not account for some other edge cases.

Next testcase step is to make another REST call, this time to our modified endpoint – still note that our REST service points to the literal ${#TestCase#endpoint}, so this will be picked up automatically. You can set an assertion for a list of Valid HTTP Status Codes to be whatever you need. Note that SoapUI by default follows redirects; these are normally the 300 status codes. If you explicitly want to see those, you will need to turn off redirect for this step in the test step properties.

crawler redirects

Lastly wrap the testcase in a DataSource loop step.

January 29, 2014

defining test categories in SoapUI

Filed under: automation — SiKing @ 1:05 pm
Tags: ,

Categories are a feature of most modern test automation frameworks, which allows you to assign an arbitrary tag to any test, and then subsequently select a group of tests to run only by that tag. JUnit introduced this feature in version 4.8, both TestNG and NUnit have had it for a while. In SoapUI you have to do some tricky naming of your test case and suites in order to be able to achieve this. Or … you could use a custom event.

You want to check for the categories before every test run, so the event has to be a TestRunListener.beforeRun event. Leave the target blank (any test case), and name it anything you like – I used “categories”.

The category tags will be specified in three places: each test is going to be tagged with a category in a property called “categories”. Then at the project level, we want to specify properties “includeCategories” and “excludeCategories”, which will list categories to include and categories to exclude, respectively. Each of these will be just a comma-separated list. First part of our event script is to read all that stuff in:

def testCategories = []
def excludeCategories = []
def includeCategories = []

def tstCats = testRunner.testCase.getPropertyValue("categories")
def exCats = testRunner.testCase.testSuite.project.getPropertyValue("excludeCategories")
def inCats = testRunner.testCase.testSuite.project.getPropertyValue("includeCategories")

if(tstCats != null) tstCats.split(',').each { testCategories << it.trim() }
if(exCats != null) exCats.split(',').each { excludeCategories << it.trim() }
if(inCats != null) inCats.split(',').each { includeCategories << it.trim() }

The first three lines each define an empty List. Next three lines read all the properties in, and the last three lines parse them. We do not want to bother the user with defining a proper List of Strings, such as ["category1", "category2", "etc."], the above code expects that the categories property just specifies something like: category1, category2, etc., no quotes, no brackets.

First let’s deal with exclude categories. The meaning of these is usually that if a test is tagged with any of these, do not run it.

// exclude categories
excludeCategories.each {
		testRunner.cancel("${} TestCase cancelled; excludeCategory = ${it}!")

And now the include categories. The meaning of these is that if the test is not tagged, skip it. Only if a test is tagged with any of these, then run it.

// include categories
if(includeCategories.size() != 0) {
	def cancelTest = true
	includeCategories.each {
			cancelTest = false

		testRunner.cancel("${} TestCase cancelled; includeCategories = ${includeCategories}!")

That is it!

As an added bonus, I can also have some automatic category handling, such as:

// Do not bother running LONG tests during work hours.
if(testCategories.contains("LONG")) {
	def rightNow = new GregorianCalendar()
	if(rightNow.get(Calendar.HOUR_OF_DAY) < 17)
		testRunner.cancel("${} test too long to bother during the day!")

Enjoy! :D

November 1, 2013

testing concurrency with SoapUI

Filed under: automation — SiKing @ 11:02 am
Tags: ,

Testing concurrency in SoapUI is easy, if you know how – just like everything else in life. :) There are several approaches that you can take.

First, let’s define what “concurrency” is. Concurrency, also called a “race condition”, is when multiple requests arrive at the server at the same time, but they each need to be handled separately. A simple example: let’s say that you have $100 in your bank account and you send several requests to withdraw all the money – obviously only one of the requests should succeed and the others should fail due to insufficient funds. If more than one of these requests succeeds, you found a race condition. The cause of concurrency is often improper database locking.

SoapUI has the ability to send requests in parallel at the project level (parallel test suites) or at the test suite level (parallel test cases). I will discuss several possible approaches based on different situations.

Note that in the below discussion in each case we are talking about only one test! However, when I use the terms “test case” and “test suite” I am talking about the level of hierarchy in a SoapUI project.

Case 1: the straightforward suite

In the simplest case you have a situation where only one of multiple requests should succeed, such as the case of withdrawing all the money from one bank account. This case assumes there is no setup or cleanup of any kind.

Start with creating a new test suite in SoapUI and setting the run mode to parallel. testcase parallel mode

Next create the first test case to make one transfer. Do not add any assertions that verify success / failure of the transfer itself – you are expecting only one to succeed and you do not know which one that is going to be. Since timing is important in a concurrency test, keep this lean. Normally I have just a single SOAP Response assertion, or a Valid HTTP Status Codes assertion (if dealing with a REST request).

Clone the test case (using F9) multiple times. As will be seen later, it is a good idea to keep the names of the test cases simple; something like: tranfer0, transfer1, transfer2, etc.

Lastly, you need to handle the verification in the test suite TearDown Script. The exact script will depend on what response you are going to get and what you are looking for. Let’s say that a failed transfer will respond with a SOAP fault, then your verification script could look like the following.

def goodTransfer = 0
testSuite.testCases.each {
	def response = new XmlHolder(it.getTestStepByName("transfer").getProperty("Response").value)
	if(response.getDomNode("//*:Fault") == null)
assert goodTransfer == 1 : "Too many transfers!"

You will have to adjust the script for your particular situation, but the idea is simple. Read the response of each of the steps (within the test cases in the SoapUI hierarchy) and count the number of successes – there had better be only one.

Case 2: login first

What if you first need to login or generate some other setup?

The only difference from case 1 is the setup – the login. Start with creating everything from case 1.

Next add a test case for the login. It does not matter where in the order of tests you place it (everything runs in parallel anyway), but it helps visually if you place it first. Make sure this test runs correctly and transfers any credentials you may need to your other steps.

Next comes the secret sauce. Disable this test case; this test must be run from the test suite Setup Script with:

testSuite.getTestCaseByName("login").run((, false)

The login could get more complicated if your application requires that HTTP session be maintained. The exact solution to your specific situation is left as an exercise for the reader. :)

Case 3a: verify afterwards (at project level)

What if, similarly to case 2, you need to run some sort of cleanup after everything has run. For example: deposit money back so that next run of the same test will work again.

You could take the same approach as in case 2: create a test case at the end of your test suite, disable it, and run it from the suite TearDown Script. However, any tests that are run this way will not get considered when determining if the suite failed or not (the final exit status of the test runner) and will not have any logs created!

In order to work around this, you could set up your entire test as a new SoapUI project. In the project, you will have three test suites: setup, transfers, and cleanup. All test suites are run sequentially, nothing gets disabled, nothing gets run from Setup or TearDown. The setup portion will have only one test case similar to the login from case 2. The transfers portion will have multiple test cases such as all the transfers from case 1 (possibly minus the verification), all run in parallel. The cleanup portion will have one test case like the deposit and any cleanup (and possibly the verification).

Practical example of this situation is that instead of withdrawing all the money from your account, you send in multiple deposits and withdrawals for smaller amounts, and then afterwards the transaction history (a separate API request?) has to show the correct running balance.

The exact implementation of all of this should be pretty straightforward if you got through all the discussion so far.

However, if you are running in a continuous integration system, it is undesirable to have a separate SoapUI project for every concurrency test.

Case 3b: verify afterwards (at test suite level)

You can have a test case wait until other test cases have completed. The magic sauce here is the SoapUI monitor.

Start by creating everything you have done in case 2.

Now create your verification test case. Just as before, it does not matter where in the test suite you place it (everything runs in parallel), but visually it makes more sense to place it at the end. This test does not get disabled, since this is where the verification will take place – you need this test to be considered in the final runner exist status and you want all the logs generated from this step.

In the test suite Setup Script initialize the monitor.

def monitor = new com.eviware.soapui.monitor.TestMonitor()
testSuite.testCases.each {
	testCase = it.value
	if(testCase.label.contains("transfer")) {"monitoring: ${testCase.label}")
runner.runContext.testMonitor = monitor

If you are less careful about how you name your test cases, the if statement above may become slightly more complicated?

	if(testCase.label.contains("withdrawal") || testCase.label.contains("deposit"))

In the last test case, the verification one, create a new Groovy Script step which will wait for everything else to complete. This step has to be first!

def monitor = context["#TestSuiteRunner#"].runContext.testMonitor
if (monitor == null) {
	log.warn("monitor not found in completion check")
} else {
	while(monitor.hasRunningTests()) {"waiting for tests to complete ...")
		try {
		} catch(InterruptedException ignored) { }
	}"Tests completed: ${!monitor.hasRunningTests()}")

July 25, 2013

SoapUI Cookie management

Filed under: automation — SiKing @ 12:09 pm
Tags: ,

It seems that HTTP session Cookie management in SoapUI is little understood. :( Performing several Google searches, supplemented by some emails to SmartBear support, yielded only a lot of confusion. Until one day I happened upon this gem by user "Unibet Support"!

Cookies are normally handled by the client in a "Cookie Store"; in SoapUI they cannot be read/set same as other parameters. I am intentionally using the upper-case C here, as one of my first attempts was: messageExchange.requestHeaders['cookie']. Through some trial and error I discovered that I could use an event like submit.request.requestHeaders['Cookie'] (with the upper-case C), however this was still not the correct path to enlightenment.

You first need to get into the Cookie jar.

def myCookieStore = HttpClientSupport.getHttpClient().getCookieStore()

Reading Cookies

def myCookies = myCookieStore.getCookies()

This will give you a List<Cookie>. An individual Cookie is going to look something like:

[version: 0][name: JSESSIONID][value: 6ed79202575ff0c178efa2d4d9f1][domain: abcd-zq11][path: /css][expiry: null]

You can access each of the items with a get method, which Groovy usually exposes as a parameter.

assert myCookies[0].getValue() == myCookies[0].value

To get one specific Cookie, you could do something like:

def interestingCookie
myCookies.each {
	if( == "JSESSIONID")
		interestingCookie = it

Updating Cookies

To update a Cookie is just as easy. Each of the get methods has a corresponding set method, again in Groovy exposed as a parameter.

interestingCookie.value = "new_cookie_value"

This, of course, updates the Cookie right in the Cookie Store! To avoid this:

def clonedCookie = interestingCookie.clone()
clonedCookie.value = "cookie_not_in_store"

Deleting Cookies


will clear out all Cookies from the Store. To delete only one specific Cookie, you could do something like:

interestingCookie.expiryDate = new Date() - 1	// yesterday
myCookieStore.clearExpired(new Date() - 1)

Creating Cookies

This is a little more involved.

import org.apache.http.impl.Cookie.BasicClientCookie
def myNewCookie = new BasicClientCookie("cookie_name", "cookie_value")
myNewCookie.version = 1
myNewCookie.domain = "qa.test"

Of course you could have done something like:

def myNewCookie = new BasicClientCookie("cookie_name", interestingCookie.value)

July 5, 2013

dynamically create elements in a SoapUI request, JSON version

Filed under: automation — SiKing @ 10:50 am
Tags: ,

One of my previous posts “dynamically create elements in a SoapUI request” seems to be quite popular – 3rd most popular by the number of hits. Well recently I had to achieve the same feat, but this time in JSON for a REST call. So I thought I’d share.

With the release of version 1.8 Groovy introduced native support for JSON.

the challenge

Transform this response of one step:

  "leagueId": 22,
  "name": "Bruins at Sabres",
  "rotation": 1401,
  "eventId": 66069,
  "status": "ACTIVE",
  "leagueName": "NHL",
  "startTime": "2013-08-17T09:05:00.000-07:00",
  "home": {
    "selectionId": 1243,
    "name": "Sabres",
    "shortName": "SAB",
    "marketId": 0
  "away": {
    "selectionId": 454,
    "name": "Bruins",
    "shortName": "BRU",
    "marketId": 0
  "markets": [
      "marketId": 428465,
      "name": "Money Line",
      "period": 11,
      "type": {
        "marketTypeId": 2,
        "basicType": "ML"
      "selections": [
          "selectionId": 454,
          "name": "Bruins",
          "shortName": "BRU",
          "position": "A",
          "priceId": 3560954,
          "price": 1.74074074,
          "usprice": "-135",
          "marketId": 428465

To make it look like this request of the next step:

  "bets": [
      "stake": "10.201259570695608",
      "selections": [
          "marketId": 428465,
          "position": "A",
          "price": 1.74074074,
          "selectionId": 454,
          "name": "Bruins",
          "priceId": 3560954,
          "shortName": "BRU",
          "usprice": "-135",
          "event": {
            "startTime": "2013-08-17T09:05:00.000-07:00",
            "leagueId": 22,
            "leagueName": "NHL",
            "eventId": 66069,
            "status": "ACTIVE",
            "rotation": 1401,
            "name": "Bruins at Sabres"

the solution

The script ended up being surprisingly simple:

import groovy.json.*
def extractSelectionJson(String from) {

	def slurper = new JsonSlurper()
	def result = slurper.parseText(context.expand('${'+ from +'#Response}'))

	def selectionMap = [:][0].selections[0].each {
		selectionMap[it.key] = it.value

	def eventMap = [:]
	result.each {
		if(it.key.equals("away") || it.key.equals("home") || it.key.equals("markets"))
		eventMap[it.key] = it.value

	selectionMap["event"] = eventMap

	def builder = new JsonBuilder(selectionMap)
	testRunner.testCase.setPropertyValue("selection", JsonOutput.prettyPrint(builder.toString()))

Let’s have a look at what is going on.

Everything lives in the groovy.json.* namespace. The JsonSlurper reads and parses JSON using the .parseText() method which takes a string as an input. I will read all of my response into the variable result. I can now access any element in my response as an attribute of result.

Inside my script I will manipulate everything as a map.

In my request, the selections element is at a higher level of hierarchy than in the response. I will read that first (using[0].selections[0]) and iterate over all the elements. If you deal a lot with XML and XPath, keep in mind that arrays in XPath are one-based (the first one is numbered 1), however Groovy (and Java) arrays are always zero-based (first one is numbered 0); in this case we are manipulating everything in pure Groovy.

Next I build up the “event” map, where all the elements come from a higher level of the hierarchy than where they go into my request. Again, read all the elements and iterate over them (result.each), but this time I want to skip some in the if block.

Repackage everything back together in selectionMap["event"] = eventMap, and rebuild / convert it all back into JSON JsonBuilder(selectionMap).

Lastly there is no way to write this out directly into my test step request, similar to what I have been able to do with SOAP requests. So I write everything out to a SoapUI property, called selection.

If you are paying attention, I never addressed the bets and stake elements. That is because in my particular case I wanted to be able to manipulate the stakes on per test basis. My request now looks like:

  "bets": [{
      "stake": "${=Math.random() + 10}",
      "selections": [${#TestCase#selection}]

One more side note. When building all this up I ran into an issue. If any of the strings in my response above contained "\\" (double slash), the JsonSlurper crashed. This is a bug in Groovy, discussed here, and allegedly fixed in Groovy 1.8.4; SoapUI ships with Groovy 1.8.0. There are two possibilities how to work around this in SoapUI.

  1. When you read in the response, you have to read it in as slurper.parseText(context.expand('${'+ from +'#Response}').replaceAll("\\\\", "")). This obliterates all the double slashes, which in some cases may be undesirable.
  2. Install latest Groovy – I used Groovy 2.1.1. Copy the file $GROOVY_HOME/embeddable/groovy-all-*.jar to $SOAPUI_HOME/lib, and remove $SOAPUI_HOME/lib/groovy-all-1.8.0.jar. This could cause problems if you are running your tests on a CI machine that you do not have direct control over.

June 9, 2013

Privacy: it doesn’t matter anymore!

Filed under: meatspace — SiKing @ 9:30 am

Eric Schmidt‘s now famous quote: “If you have something that you don’t want anyone to know, maybe you shouldn’t be doing it in the first place” is sometimes used as justification for invading people’s right to privacy.

Personally I have nothing to hide, and overall I think I lead a rather dull spartan life, which suits me very well. So I have nothing to worry about, right?

It is becoming common practice when you apply for a job to have to go through a background check. And in this brave new world we do everything instantly and online. I have recently applied for a volunteer position, and so was asked to submit to a background heck. Love the word “submit” in that request, BTW! After I paid them $35 – yes, not only am I about to get anally raped by some Internet leach, but I have to pay them money for the privilege – the results came back: irrelevant.

There are more and more of these so called services springing up. And they are for profit companies. For a for profit company it makes perfect business sense to differentiate yourself from your competition – to come up with something new. My report came back with something like two-dozen variations of my name. I am pretty sure there is only one of me, however there are now over 20 other people attached to my SSN. Now I am one of the lucky ones, and my name is not very common, however for people with common names this has to be a friggin’ nightmare. But at least the company that did the search did cover themselves in the EULA by stating that if any of the information they produce is wrong, it’s not their fault!?!? If one of my so-called aliases has a brush with the law, that could potentially mean the end of my career. There is no recourse for me to have my information removed from their system, because that would be contradictory to their business model. And even if there ever comes a day that I could legally demand my information be removed, there is no delete button on the Internet!

This isn’t a problem with privacy, this is a problem that someone who only cares about the bottom line is holding my future in their hands.

May 29, 2013

It’s a sad world

Filed under: meatspace — SiKing @ 8:52 am

When I was a kid I was obsessed with Start Trek. There was one episode where two planets fought a war all through a computer simulation. One computer launched a simulated attack, the other side simulated a response, and then the computers calculated casualties. Actual people had to report to “extermination booths” where they were swiftly and painlessly exterminated.
We are getting pretty close to accomplishing this.
It’s all great that in the course of fighting terrorism no American lives will be lost. However, the thing that we seem to have missed from the 1967 TV show, is that by making war clean and pretty, and removing all the pain and suffering, we have removed the very reason to STOP!

February 28, 2013

What is wrong with GroovyTestCase and Selenium?

Filed under: automation — SiKing @ 2:58 pm
Tags: ,

Sometime ago I had a problem with running Selenium with GroovyTestCase framework. Recently I started a new project and have spent some time looking at this again.

Short answer: user error! :o

Long answer:

The problem

I instantiated all my stuff like this:

class MyTestSuite extends GroovyTestCase {
      WebDriver driver = new FirefoxDriver()
      // ... some other global variables go here

      protected void setUp() throws Exception {
            // ... some other code to run at the start of each test

      protected void tearDown() throws Exception {

      void test_one() {
            // ... more test code goes here

      void test_two() {
            // ... more test code goes here

Each time I ran any of the tests, it launched like four browser windows and ran the test in one of them. :?

new FirefoxDriver() launches the new browser, as it is suppose to. The framework, I guess, launched the class four times, once for each of my methods, and Groovy automatically places that code in the constructor. It then started parsing for all the work (all the test* methods).

The solution

You need to launch the browser (only once per test) from the setUp(), like so:

class MyTestSuite extends GroovyTestCase {
      WebDriver driver
      // ... some other global variables go here

      protected void setUp() throws Exception {
            driver = new FirefoxDriver()
            // ... some other code to run at the start of each test

      protected void tearDown() throws Exception {

      void test_one() {
            // ... more test code goes here

      void test_two() {
            // ... more test code goes here

HTH, ;)

February 1, 2013

Noki Déjà vu

Filed under: noki — SiKing @ 8:56 am

After 6 years my phone finally died. People (some people) are freaked out that I have had a phone for 6 years. However, when I purchased it, I had all intentions of keeping it for at least 10! It powers on, however the keyboard is completely unresponsive. Actually for a few years I had been unable to reflash the OS. Unfortunately the phone took down my entire phonebook with it.

Getting a new phone was like déjà vu, or is that reja vu?

For like a year now I have been talking about getting a new (the?) phone, and actually trying to bid cheap on it on eBay. When my old phone died, due to some personal circumstances, I needed a phone like right now! I just went to Target and got whatever was the cheapest thing in stock. After a few days I decided that all I really need is a phone … that’s it! Just a phone that can make calls, and send the odd SMS text. So one last time I decided to have a browse through eBay, just to see what the current price point is on the N9. When I logged into my account I had a message … from a seller: “where the heck is my money for the phone you bought a week ago?!?!” That’s paraphrased, of course. This was a total surprise. I discovered that eBay completely redesigned their site! Auctions that you are either bidding on and have lost are easily accessible from the left navigation menu (even though the counts are updated correctly only after you click on one of the links). But auctions that you have actually won, are buried at the bottom of the “Summary” page. :mad:

I apologized to the seller and paid for the phone right away. Since I am getting a new shiny phone, I even paid for the extra $20 faster shipping. Afterwards, on a whim, I decided to check the seller’s eBay store. The seller is from Hong Kong, and at the top of the storefront was a message: “tomorrow is the start of the Chinese New year celebrations, and so we will be shutting down for a month!” :shock:

Update Feb.19: And it does not end there. The seller shipped it to the wrong address (someplace in California). USPS says they will wait 30 days and ship it back if it is unclaimed. :sad:

Probably faith telling me that the cheapo is good enough for me?

July 25, 2012

SoapUI external XML DataSource

Filed under: automation — SiKing @ 2:57 pm
Tags: ,

I am normally not a fan of DDT, I tend to lean more towards BDT, so it was only very recently that I started looking at the DataSource test step in SoapUI. The available documentation has a lot of room for improvement. Here is how I was able to use an external XML file(s) as a data source for my test.

I was given three files that have filenames like Visa_AVS.xml and they contain data in the form:

<test accountNumber="4112344112344113" amount="1.00" street="1 Main Street" city="Boston" zip="031010001" expectedAvsResp="B" />

Step 1: read in the raw files

This is done with the DataSource step.

The only thing that I could find to read in a file (other than Excel) is the DataSource = Directory.

I am using SoapUI-Pro and my entire project is a Composite Project, so every TestSuite is a separate directory. I am going to keep all my data sources in the same directory as the TestSuite, so as to make it easier for uploading to SVN. Directory = ${projectDir}/AA-PPS-soapui-project/experimental-Test-Responses-TestSuite

The Filename Filter = *_AVS.xml should be pretty explanatory. The only thing worth mentioning is that the filter must start with an asterix – probably a bug in SoapUI.

At this point there is no way to format the data, so the entire contents will be read into only one Property. It does not matter what you call it; I used “allData“.

I know I have three files, so when I hit the play button, I should get three entries in the Data Log.

DataSource - file

Step 2: format the data

This is also done with a DataSource step.

This time we are dealing with DataSource = XML.

Note that the documentation for Source Step says: “could be another DataSource”. Source Step = DataSource – file (from Step 1).

Source Property = allData – the only one you created in Step 1.

You need the XPath that would select each of the data blocks in your source file. Row XPath = //test

Next start creating the Properties. If you prefer to visualize your data as a spreadsheet grid, then the Row XPath would be each of your rows, and the Properties will be each of the columns. I decided to name each Property after the data attributes, but you can name them anything you like. As soon as you create a Property, the form will automatically start inserting new Column XPaths. The form assumes that your source data is formatted something like:


and so it inserts XPath like accountNumber/text(). In my case this is not correct, so I needed to Edit this to say @accountNumber. One of my source files, instead of the attribute zip, has an attribute zip5. So I had to edit the XPath to “@zip | @zip5“.

Once you hit the play button, you should see correct data in the Data Log. If you did anything wrong there will probably not be an error, you will just not see correct (any?) data in the Data Log.

DataSource - XML

Step 3: your test steps

At this point you can use any number of any test steps you like. Any of the data above can be accessed with Property expansion, for example ${DataSource - XML#accountNumber}, and can be manipulated just as any other data either in Input or in Assertions.

Step 4: iterate over all data

You need to add two DataSourceLoop steps.

The first will iterate over all the data within one file. So the DataSource Step should be whatever you named your Step 2 above. The Target Step should probably be whatever is the first thing in Step 3 above.

The second iterates over all the files. So the DataSource Step should be whatever you named your Step 1 above. The Target Step should be Step 2 above.

Test Case


HTH. ;)

March 20, 2012

debugging SoapUI Groovy scripts in Eclipse

Filed under: automation — SiKing @ 4:27 pm
Tags: ,

The very first thing that I must say: I did not quite get it to work, yet! I am hoping that somebody out there will read this and prod me in the right direction to get the last bit to work – please be gentle.

Step 1: ready SoapUI

You need the Pro version to get this to work, because using this technique you can only debug stuff in the Groovy Script Library.
I have two installations of SoapUI: version 4.0.1 that I use just for debugging, and version 4.0.2 SNAPSHOT that I use for all other work. But that might be a little overkill. :razz:

  1. Download/install/configure SoapUI Pro. The most important thing is that you need to refactor any script you want to debug into the script library.
  2. Download and unpack the SoapUI source into the same directory as the installation.
  3. Modify the SoapUI Bootstrap Script; depending on which platform you are running this is going to be in $SOAPUI_HOME/bin/ or %SOAPUI_HOME%\bin\soapui-pro.bat if you’re a Window$ weenie. The last line of the script reads something like: java $JAVA_OPTS -cp $SOAPUI_CLASSPATH com.eviware.soapui.SoapUIPro "$@". Modify it to say java $JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8666 -cp $SOAPUI_CLASSPATH com.eviware.soapui.SoapUIPro "$@". The details of what this does can be found in this DW article, by Charles Lu.

Step 2: ready Eclipse

Don’t bother with the Eclipse-SoapUI plugin; not only does it not support any of the Pro features, but it is completely useless.

  1. Download/install/configure Eclipse. I personally prefer Eclipse for Testers, with the Java tools and Groovy tools installed.
  2. Create a new Groovy project and import into it your SoapUI project. Make sure you specify that your scripts folder is where your source files are stored.

    specify scripts as your source folder name

  3. You will need to link in the soapui-pro-4.0.1.jar library with the attached sources, as well as everything in the lib directory as a user library.

    create a user library from everything in $SOAPUI_HOME/lib

    add the soapui-pro-4.0.1.jar and the SoapUI user library to the build path

  4. Create a New Debug Configuration. It is going to be a Remote Java Application running on localhost:8666 to match the port specified when launching SoapUI above.

    create a debug configuration

Step 3: debug

  1. Start SoapUI from the modified script. You should see a message something like: Listening for transport dt_socket at address: 8666.
  2. Fire up Eclipse and start the debug configuration. It should connect to the already running SoapUI.
  3. In Eclipse, in one of your scripts set a breakpoint. In SoapUI run the test that contains this script.
  4. My Eclipse Debug session stops in the correct spot, however:

    now what?

Would appreciate any hints how to resolve this. :cry:

Next Page »

The Rubric Theme. Blog at


Get every new post delivered to your Inbox.