Thursday, July 31, 2008

Snag Installing Ganymede on Hardy w/ Firefox 3

I had an issue installing Eclipse 3.4 Ganymede on Ubuntu Hardy. Eclipse would start to load until I was greeted with a blank error window.

I found this post that guided me in the right direction:

Eclipse just crashed so I’m going to file a bug now…

I was getting the following error mentioned in the above post:
  org.eclipse.swt.SWTError: XPCOM error -2147467262
Accompanying the error was another error "Widget closed too soon!", which turned out to be related to the Welcome screen, which was being displayed since I had a fresh installation.

The bug post for this issue had a couple of suggestions.

First, since I am using Firefox 3, I tried moved /usr/lib/xulrunner-1.9b5 as a few kind people suggested. Ganyemede came up just fine, but Firefox would no longer work.

An alternative workaround mentioned first creating your workspace with Eclipse 3.x, closing the Welcome screen, and the running Ganyemede. I installed Eurpoa 3.3.2, restored xulrunner-1.9b5, ran Eurpoa, and then was able to bring Firefox and Ganyemede up with no problems.

Wednesday, July 30, 2008

XML Unit Testing with Groovy and XMLUnit

A while back I needed to compare XML documents during my unit testing. The documents, or snippets actually, were small enough and I had enough control over how they were created, that simple comparisons of the expected and actual results were enough. After a while as the snippets grew larger I ran into a few problems. For one, if I didn't use StreamingMarkupBuilder to create the XML, whitespace became an issue. And more importantly, "equivalent" XML would compare differently if the order of the elements of a node were not in the same order.

Eventually, I found a few lines of code in the Groovy user guide that turned me onto XMLUnit, at the bottom of the first example:
Groovy Example

The following line quickly took care of the whitespace issue.
import org.custommonkey.xmlunit.*
XMLUnit.setIgnoreWhitespace(true)
For testing equivalent XML, XMLUnit allows to expect child elements in a exact order (identical) or not (similar):
def photoguy = new StreamingMarkupBuilder().bind {
person {
firstname('Larry')
lastname('Appleton')
}
}

// equivalent, but different ordered child elements
def balkisCousin = new StreamingMarkupBuilder().bind {
person {
lastname('Appleton')
firstname('Larry')
}
}

def xmlDiff = new Diff(photographer, balkisCousin)
assert ! XmlDiff.identical()
assert xmlDiff.similar()
Down the road, I ran into the situation where I wanted to allow a difference in a particular element. The element contents were quite large and subject to change and I didn't really need to cover the results in this part of my project. Furthermore, I didn't want to store the actual result as it was that particular day in my test resources I used for the expected results. Naively, I could make an assertion about every other element in the snippet I cared about and ignore the one that might produce a difference, but that wouldn't be good for my mental health.

Luckily, XMLUnit gave me what I needed, in this case I'm allowing one difference:
String expectedXml = getClass().getClassLoader().getResourceAsStream(testFile).getText()
def xmlDiff = new Diff(personAsXml, expectedXml)
assert !xmlDiff.similar()
assert !xmlDiff.identical()

def detailedDiff = new DetailedDiff(xmlDiff)
def differences = detailedDiff.getAllDifferences()
assertEquals detailedDiff.toString(), 1, differences.size()

def location = differences.pop().getTestNodeDetail().getXpathLocation()
// a regex may be better for this?
def expectedLocation = '/person[1]/employment[1]/company[1]/text()[1]'
assertEquals expectedLocation, location
XMLUnit has a whole bunch of other features that I have not gone back to check out yet. Maybe somebody else has and would be kind enough to drop a comment. A new version, 1.2, came out in June.