Simple XML Testing from Java
Join the DZone community and get the full member experience.
Join For Free2009 is coming to a close and I'm writing a blog post about Java and
XML. The blog's called "behind the times" for a reason: no fancy
dynamic languages, JSON, or REST. Straight up XML on Java action.
One of my favorite editions to our enterprise toolset this year was XMLUnit. We'd been using Groovy in testing, and multi-line strings led to a ton of expressiveness in test cases...
but then we stopped using Groovy. I switched back to Java testing and
was left with making String based assertions and doing
String#contains() calls. Not ideal; enter XMLUnit.
XMLUnit supports XML based equality comparisons so that things like these two snippets are equal:
<root/> <root></root>
As well as these:
<root>data</root> <root> data </root>
In fact, there's a whole gaggle of options around what is a meaningful versus a meaningless difference. For instance, I often consider two dates equal as long as they are formatted correctly (ignoring those pesky timestamp issue is nice).
The problem with XMLUnit is that the API is not as nice for the simple case as it could be. What I want is a simple custom assertion that asserts two XML snippets as similar. Something like this:
XmlAssertions.assertXmlSimilar("<root/>", "<root></root>");
XmlAssertions.assertXmlSimilar("<root>data</root>", "<root>\ndata\n</root>\n");
This was as simple as creating a small utility class and hiding the XMLUnit API behind a nicer custom assertion:
import java.util.List;
import junit.framework.*;
import org.custommonkey.xmlunit.*;
public class XmlAssertions {
private static final String ERROR_MSG = "XML comparison failure. \nExpected: %s\nReceived: %s\n%s";
static {
XMLUnit.setIgnoreWhitespace(true);
}
public static void assertXmlSimilar(String expected, String actual) {
try {
Diff diff = new Diff(expected, actual);
List differences = new DetailedDiff(diff).getAllDifferences();
Assert.assertTrue(
String.format(ERROR_MSG, expected, actual, differences),
diff.similar());
} catch (Exception ex) {
Assert.fail(String.format(ERROR_MSG, expected, actual, ex.getMessage()));
}
}
}
The raw XMLUnit code is clearly not something you want to see within the body of a test method. The custom assertion seems simple, but it's made a real pleasure of writing XML based functional tests around all our web services. Feel free to steal my code here: http://svn.assembla.com/svn/SampleCode/xmlunit/XmlAssertions.java
Opinions expressed by DZone contributors are their own.
Comments