SiKing

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 {
	if(testCategories.contains(it))
		testRunner.cancel("${context.testCase.name} 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 {
		if(testCategories.contains(it))
			cancelTest = false
	}

	if(cancelTest)
		testRunner.cancel("${context.testCase.name} 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("${context.testCase.name} 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.

import com.eviware.soapui.support.XmlHolder
def goodTransfer = 0
testSuite.testCases.each {
	def response = new XmlHolder(it.getTestStepByName("transfer").getProperty("Response").value)
	if(response.getDomNode("//*:Fault") == null)
		goodTransfer++
}
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((com.eviware.soapui.support.types.StringToObjectMap)context, 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")) {
		log.info("monitoring: ${testCase.label}")
		monitor.monitorTestCase(testCase)
	}
}
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()) {
		log.info("waiting for tests to complete ...")
		try {
			Thread.sleep(100)
		} catch(InterruptedException ignored) { }
	}
	log.info("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.

import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport
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(it.name == "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

myCookieStore.clear()

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"
myCookieStore.addCookie(myNewCookie)

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 = [:]
	result.markets[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"))
			return
		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 result.markets[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
Tags:

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
Tags:

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 {
            super.setUp()
            // ... some other code to run at the start of each test
      }

      protected void tearDown() throws Exception {
            driver.quit()
            super.tearDown()
      }

      void test_one() {
            driver.get("some_website")
            // ... more test code goes here
      }

      void test_two() {
            driver.get("some_other_website")
            // ... 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 {
            super.setUp()
            driver = new FirefoxDriver()
            // ... some other code to run at the start of each test
      }

      protected void tearDown() throws Exception {
            driver.quit()
            super.tearDown()
      }

      void test_one() {
            driver.get("some_website")
            // ... more test code goes here
      }

      void test_two() {
            driver.get("some_other_website")
            // ... more test code goes here
      }
}

HTH, ;)

February 1, 2013

Noki Déjà vu

Filed under: noki — SiKing @ 8:56 am
Tags:

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:

<test>
   <accountNumber>4112344112344113</accountNumber>
   ...
</test>

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/soapui-pro.sh 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:

March 4, 2012

Zeroth law of Life

Filed under: meatspace — SiKing @ 10:06 am

Scientists discover laws of Universe – how the universe works. Engineers are paid to break them. There is however the Zeroth law of Engineering – law that no other can supersede and nobody can break. The concept is named after Asimov’s Zeroth law of Robotics. The Zeroth law of Engineering states that any project can be good (quality), fast (on time), or cheap (on budget), pick two!

My Zeroth law of Life states that you can be good (morally, ethically, legally, spiritually, whatever…), rich (at least comfortably), or happy, pick two! Personally I have struggled my whole life to get a firm grip on at least one of these.

February 26, 2012

Loop around Area51

Filed under: rides — SiKing @ 10:00 pm
Tags:

CeeJ and I have been mulling around riding the Extraterrestrial Highway for a while. This weekend we made it happen.

Day 1

The plan was to start early afternoon (after CutiePie’s swim practice). Unfortunately, CJ’s Shadow made it as far as the end of his street before it took a dump and would not start again. He had to push it back up to his house and change bikes, obviously moving everything he packed the nigh before from one bike to a backpack. We left Vegas probably around 3 in the afternoon.

The ride up the 95 went by pretty uneventful. CutiePie took some pictures from the back – of her gloves, her pants, the asphalt – and filled up the camera memory. Mental note: the camera memory is not a good backup storage. :???: CJ reported that CutiePie was occasionally practising her synchro moves on the back of the bike – too bad we don’t have any video of that. Beatty was the first gas stop, next to The candy store of course. :)

Onwards through Goldfield up to Tonopah. Both of these are quickly becoming ghost towns, leftovers from the gold-rush days. I was actually very pleasantly surprised how well maintained the town centre of both towns was.

Day 2

I woke up the next day around 8 (we did say no rush, right!), with both CJ and CutiePie both staring at me like: can we go yet? After the continental breakfast (mmmmm bacon! :razz:) we took a short walk around Tonopah. One, we wanted to gauge the morning temperature, and two, we wanted to see the town in daylight. If you are going to stay, I recommend the Mizpah hotel – it still has the old charm to it. We did not get a room there (no vacancy), but did have our dinner there. Eventually opted for for the winter riding pants, since I brought them along, but not the extra sweat shirt.

We got on the road probably just before 11. By this time I was sweating like a pig! About 40 miles out of town, I decided to pull over on the side of the road to zip up all the vents on my jacket and pants. The temps were getting below freezing, before the wind chill factor! A state trooper just happen to drive by, and pulled over to ask us if we were OK. On a whim I asked him if we are heading the right way towards the 375. He told us that we are headed exactly the opposite direction! We need to go back through Tonopah, and take the 6 towards Ely. The freaky thing is that about 5 miles back we passed a rest stop, where I was originally thinking of stopping to zip up, and where the trooper would have never seen us. By the time we were back in Tonopah, I had to gas up again, especially considering the next gas after that was going to be in Alamo – about 160 miles away; my bike has a range of 150 miles, riding 1up, down hill, with a good strong back wind. And off we were again, this time in the right direction.

The first stop we made was at the turnoff to the Tonopah Test Range airport – apparently this is where all the testing for the Stealth fighter was done. Half-way to Ely is the turnoff to the 375 – the Extraterrestrial Highway. As soon as we turned onto the highway, I remember seeing very tall mountains on the horizon, completely covered in white, and thinking that sure I sure hope that is not where we are going. :eek: The mountains stayed to the horizon all the way. :) CutiePie kept up with her synchro workout on the back of the bike, and was freaking out the local Air Force as well as the UFOs: “What’s with the crazy air traffic controller chick?!?!” :grin:

About half-way down the 375, in Rachel, NV, you actually come to the a sign that declares this to be the Extraterrestrial Highway, right before the Little A’Le’Inn – most people pronounce it little alien inn. As CJ said: you cannot pass up the opportunity to have lunch at a dive in the middle of nowhere! :) This is where you can also find maps and photographs of the super-secret-illegal-to-photograph Area 51! The Eastern end of the highway even has some neat twisties – overall a really fun ride!

Last stop was the Alamo, NV. Brings back memories of bygone days, when I got almost abandoned by Bonnie and almost ran out of gas in the middle of the desert in the middle of the summer! This time I heeded the “No gas for next 75 miles” sign, a filled up.

This slideshow requires JavaScript.

To find Groom Dry Lake on the map, where the actual Area 51 is located, is left as an exercise for the reader.

Next Page »

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.